BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslx_genericinstream.h
Go to the documentation of this file.
1/// @file bslx_genericinstream.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslx_genericinstream.h -*-C++-*-
8#ifndef INCLUDED_BSLX_GENERICINSTREAM
9#define INCLUDED_BSLX_GENERICINSTREAM
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslx_genericinstream bslx_genericinstream
15/// @brief Unexternalization of fundamental types from a parameterized stream.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslx
19/// @{
20/// @addtogroup bslx_genericinstream
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslx_genericinstream-purpose"> Purpose</a>
25/// * <a href="#bslx_genericinstream-classes"> Classes </a>
26/// * <a href="#bslx_genericinstream-description"> Description </a>
27/// * <a href="#bslx_genericinstream-generic-byte-format-parser"> Generic Byte-Format Parser </a>
28/// * <a href="#bslx_genericinstream-usage"> Usage </a>
29/// * <a href="#bslx_genericinstream-example-1-basic-unexternalization"> Example 1: Basic Unexternalization </a>
30/// * <a href="#bslx_genericinstream-example-2-sample-streambuf-implementation"> Example 2: Sample STREAMBUF Implementation </a>
31///
32/// # Purpose {#bslx_genericinstream-purpose}
33/// Unexternalization of fundamental types from a parameterized stream.
34///
35/// # Classes {#bslx_genericinstream-classes}
36///
37/// - bslx::GenericInStream: parameterized input stream for fundamental types
38///
39/// @see bslx_streambufinstream, bslx_genericoutstream
40///
41/// # Description {#bslx_genericinstream-description}
42/// This component implements a parameterized input stream
43/// class, `bslx::GenericInStream`, that provides platform-independent input
44/// methods ("unexternalization") on values, and arrays of values, of
45/// fundamental types, and on `bsl::string`.
46///
47/// The `bslx::GenericInStream` type reads from a compliant user-supplied buffer
48/// (see @ref bslx_genericinstream-generic-byte-format-parser directly, with no data copying or
49/// assumption of ownership. The user must therefore make sure that the
50/// lifetime and visibility of the buffer is sufficient to satisfy the needs of
51/// the input stream.
52///
53/// This component is intended to be used in conjunction with the
54/// @ref bslx_genericoutstream "externalization" component. Each input method of
55/// `bslx::GenericInStream` reads either a value or a homogeneous array of
56/// values of a fundamental type, in a format that was written by the
57/// corresponding `bslx::GenericOutStream` method. In general, the user of
58/// this component cannot rely on being able to read data that was written by
59/// any mechanism other than `bslx::GenericOutStream`.
60///
61/// The supported types and required content are listed in the `bslx`
62/// package-level documentation under "Supported Types".
63///
64/// Note that input streams can be *invalidated* explicitly and queried for
65/// *validity*. Reading from an initially invalid stream has no effect.
66/// Attempting to read beyond the end of a stream will automatically invalidate
67/// the stream. Whenever an inconsistent value is detected, the stream should
68/// be invalidated explicitly.
69///
70/// ## Generic Byte-Format Parser {#bslx_genericinstream-generic-byte-format-parser}
71///
72///
73/// The class `bslx::GenericInStream` is parameterized by a buffered stream
74/// class, `STREAMBUF`, which, given the declarations:
75/// @code
76/// char c;
77/// int len;
78/// const char *s;
79/// STREAMBUF *sb;
80/// @endcode
81/// must make the following expressions syntactically valid, with the assert
82/// statements highlighting the expected return values:
83/// @code
84/// STREAMBUF::traits_type::int_type eof = STREAMBUF::traits_type::eof();
85/// assert(eof != sb->sbumpc());
86/// assert(eof != sb->sgetc());
87/// assert(len == sb->sgetn(s, len));
88/// @endcode
89/// Suitable choices for `STREAMBUF` include any class that implements the
90/// `bsl::basic_streambuf` protocol.
91///
92/// The class `bslx::StreambufInStream` is a `typedef` for
93/// `bslx::GenericInStream<bsl::streambuf>`.
94///
95/// ## Usage {#bslx_genericinstream-usage}
96///
97///
98/// This section illustrates intended use of this component. The first example
99/// depicts usage with a `bsl::stringbuf`. The second example replaces the
100/// `bsl::stringbuf` with a user-defined `STREAMBUF`.
101///
102/// ### Example 1: Basic Unexternalization {#bslx_genericinstream-example-1-basic-unexternalization}
103///
104///
105/// Suppose we wish to implement a (deliberately simple) `MyPerson` class as a
106/// value-semantic object that supports BDEX externalization and
107/// unexternalization. In addition to whatever data and methods that we choose
108/// to put into our design, we must supply three methods having specific names
109/// and signatures in order to comply with the BDEX protocol: a class method
110/// `maxSupportedBdexVersion`, an accessor (i.e., a `const` method)
111/// `bdexStreamOut`, and a manipulator (i.e., a non-`const` method)
112/// `bdexStreamIn`. This example shows how to implement those three methods.
113///
114/// In this example we will not worry overly about "good design" of the
115/// `MyPerson` component, and we will declare but not implement illustrative
116/// methods and free operators, except for the three required BDEX methods,
117/// which are implemented in full. In particular, we will not make explicit use
118/// of `bslma` allocators; a more complete design would do so:
119///
120/// First, we implement `MyPerson`:
121/// @code
122/// class MyPerson {
123/// bsl::string d_firstName;
124/// bsl::string d_lastName;
125/// int d_age;
126///
127/// friend bool operator==(const MyPerson&, const MyPerson&);
128///
129/// public:
130/// // CLASS METHODS
131///
132/// /// Return the maximum valid BDEX format version, as indicated by
133/// /// the specified `versionSelector`, to be passed to the
134/// /// `bdexStreamOut` method. Note that it is highly recommended that
135/// /// `versionSelector` be formatted as "YYYYMMDD", a date
136/// /// representation. Also note that `versionSelector` should be a
137/// /// *compile*-time-chosen value that selects a format version
138/// /// supported by both externalizer and unexternalizer. See the
139/// /// `bslx` package-level documentation for more information on BDEX
140/// /// streaming of value-semantic types and containers.
141/// static int maxSupportedBdexVersion(int versionSelector);
142///
143/// // CREATORS
144///
145/// /// Create a default person.
146/// MyPerson();
147///
148/// /// Create a person having the specified `firstName`, `lastName`,
149/// /// and `age`.
150/// MyPerson(const char *firstName, const char *lastName, int age);
151///
152/// /// Create a person having the value of the specified `original`
153/// /// person.
154/// MyPerson(const MyPerson& original);
155///
156/// /// Destroy this object.
157/// ~MyPerson();
158///
159/// // MANIPULATORS
160///
161/// /// Assign to this person the value of the specified `rhs` person,
162/// /// and return a reference to this person.
163/// MyPerson& operator=(const MyPerson& rhs);
164///
165/// /// Assign to this object the value read from the specified input
166/// /// `stream` using the specified `version` format, and return a
167/// /// reference to `stream`. If `stream` is initially invalid, this
168/// /// operation has no effect. If `version` is not supported, this
169/// /// object is unaltered and `stream` is invalidated, but otherwise
170/// /// unmodified. If `version` is supported but `stream` becomes
171/// /// invalid during this operation, this object has an undefined, but
172/// /// valid, state. Note that no version is read from `stream`. See
173/// /// the `bslx` package-level documentation for more information on
174/// /// BDEX streaming of value-semantic types and containers.
175/// template <class STREAM>
176/// STREAM& bdexStreamIn(STREAM& stream, int version);
177///
178/// //...
179///
180/// // ACCESSORS
181///
182/// /// Return the age of this person.
183/// int age() const;
184///
185/// /// Write the value of this object, using the specified `version`
186/// /// format, to the specified output `stream`, and return a reference
187/// /// to `stream`. If `stream` is initially invalid, this operation
188/// /// has no effect. If `version` is not supported, `stream` is
189/// /// invalidated, but otherwise unmodified. Note that `version` is
190/// /// not written to `stream`. See the `bslx` package-level
191/// /// documentation for more information on BDEX streaming of
192/// /// value-semantic types and containers.
193/// template <class STREAM>
194/// STREAM& bdexStreamOut(STREAM& stream, int version) const;
195///
196/// /// Return the first name of this person.
197/// const bsl::string& firstName() const;
198///
199/// /// Return the last name of this person.
200/// const bsl::string& lastName() const;
201///
202/// //...
203///
204/// };
205///
206/// // FREE OPERATORS
207///
208/// /// Return `true` if the specified `lhs` and `rhs` person objects have
209/// /// the same value, and `false` otherwise. Two person objects have the
210/// /// same value if they have the same first name, last name, and age.
211/// bool operator==(const MyPerson& lhs, const MyPerson& rhs);
212///
213/// /// Return `true` if the specified `lhs` and `rhs` person objects do not
214/// /// have the same value, and `false` otherwise. Two person objects
215/// /// differ in value if they differ in first name, last name, or age.
216/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs);
217///
218/// // ========================================================================
219/// // INLINE FUNCTION DEFINITIONS
220/// // ========================================================================
221///
222/// // CLASS METHODS
223/// inline
224/// int MyPerson::maxSupportedBdexVersion(int /* versionSelector */) {
225/// return 1;
226/// }
227///
228/// // CREATORS
229/// inline
230/// MyPerson::MyPerson()
231/// : d_firstName("")
232/// , d_lastName("")
233/// , d_age(0)
234/// {
235/// }
236///
237/// inline
238/// MyPerson::MyPerson(const char *firstName, const char *lastName, int age)
239/// : d_firstName(firstName)
240/// , d_lastName(lastName)
241/// , d_age(age)
242/// {
243/// }
244///
245/// inline
246/// MyPerson::~MyPerson()
247/// {
248/// }
249///
250/// template <class STREAM>
251/// STREAM& MyPerson::bdexStreamIn(STREAM& stream, int version)
252/// {
253/// if (stream) {
254/// switch (version) { // switch on the 'bslx' version
255/// case 1: {
256/// stream.getString(d_firstName);
257/// if (!stream) {
258/// d_firstName = "stream error"; // *might* be corrupted;
259/// // value for testing
260/// return stream; // RETURN
261/// }
262/// stream.getString(d_lastName);
263/// if (!stream) {
264/// d_lastName = "stream error"; // *might* be corrupted;
265/// // value for testing
266/// return stream; // RETURN
267/// }
268/// stream.getInt32(d_age);
269/// if (!stream) {
270/// d_age = 999; // *might* be corrupted; value for testing
271/// return stream; // RETURN
272/// }
273/// } break;
274/// default: {
275/// stream.invalidate();
276/// }
277/// }
278/// }
279/// return stream;
280/// }
281///
282/// // ACCESSORS
283/// inline
284/// int MyPerson::age() const
285/// {
286/// return d_age;
287/// }
288///
289/// template <class STREAM>
290/// STREAM& MyPerson::bdexStreamOut(STREAM& stream, int version) const
291/// {
292/// switch (version) {
293/// case 1: {
294/// stream.putString(d_firstName);
295/// stream.putString(d_lastName);
296/// stream.putInt32(d_age);
297/// } break;
298/// default: {
299/// stream.invalidate();
300/// } break;
301/// }
302/// return stream;
303/// }
304///
305/// inline
306/// const bsl::string& MyPerson::firstName() const
307/// {
308/// return d_firstName;
309/// }
310///
311/// inline
312/// const bsl::string& MyPerson::lastName() const
313/// {
314/// return d_lastName;
315/// }
316///
317/// // FREE OPERATORS
318/// inline
319/// bool operator==(const MyPerson& lhs, const MyPerson& rhs)
320/// {
321/// return lhs.d_firstName == rhs.d_firstName &&
322/// lhs.d_lastName == rhs.d_lastName &&
323/// lhs.d_age == rhs.d_age;
324/// }
325///
326/// inline
327/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs)
328/// {
329/// return !(lhs == rhs);
330/// }
331/// @endcode
332/// Then, we can exercise the new `MyPerson` value-semantic class by
333/// externalizing and reconstituting an object. First, create a `MyPerson`
334/// `janeSmith1` and a `bslx::GenericOutStream` `outStream1`:
335/// @code
336/// MyPerson janeSmith1("Jane", "Smith", 42);
337/// bsl::stringbuf buffer1;
338/// bslx::GenericOutStream<bsl::stringbuf> outStream1(&buffer1, 20131127);
339/// const int VERSION1 = 1;
340/// outStream1.putVersion(VERSION1);
341/// janeSmith1.bdexStreamOut(outStream1, VERSION1);
342/// assert(outStream1.isValid());
343/// @endcode
344/// Next, create a `MyPerson` `janeCopy1` initialized to the default value, and
345/// assert that `janeCopy1` is different from `janeSmith1`:
346/// @code
347/// MyPerson janeCopy1;
348/// assert(janeCopy1 != janeSmith1);
349/// @endcode
350/// Then, create a `bslx::GenericInStream` `inStream1` initialized with the
351/// buffer from the `bslx::GenericOutStream` object `outStream1` and
352/// unexternalize this data into `janeCopy1`:
353/// @code
354/// bslx::GenericInStream<bsl::stringbuf> inStream1(&buffer1);
355/// int version1;
356/// inStream1.getVersion(version1);
357/// janeCopy1.bdexStreamIn(inStream1, version1);
358/// assert(inStream1.isValid());
359/// @endcode
360/// Finally, `assert` the obtained values are as expected and display the
361/// results to `bsl::stdout`:
362/// @code
363/// assert(version1 == VERSION1);
364/// assert(janeCopy1 == janeSmith1);
365///
366/// if (janeCopy1 == janeSmith1) {
367/// bsl::cout << "Successfully serialized and de-serialized Jane Smith:"
368/// << "\n\tFirstName: " << janeCopy1.firstName()
369/// << "\n\tLastName : " << janeCopy1.lastName()
370/// << "\n\tAge : " << janeCopy1.age() << bsl::endl;
371/// }
372/// else {
373/// bsl::cout << "Serialization unsuccessful. 'janeCopy1' holds:"
374/// << "\n\tFirstName: " << janeCopy1.firstName()
375/// << "\n\tLastName : " << janeCopy1.lastName()
376/// << "\n\tAge : " << janeCopy1.age() << bsl::endl;
377/// }
378/// @endcode
379///
380/// ### Example 2: Sample STREAMBUF Implementation {#bslx_genericinstream-example-2-sample-streambuf-implementation}
381///
382///
383/// For this example, we will implement `MyStreamBuf`, a minimal `STREAMBUF` to
384/// to be used with `bslx::GenericInStream` and `bslx::GenericOutStream`. The
385/// implementation will consist of only what is required of the type. For
386/// comparison, we will reuse `MyPerson` and repeat part of {Example 1} to
387/// demonstrate how to use `bslx::GenericInStream`.
388///
389/// First, we implement `MyStreamBuf` (which, for brevity, simply uses the
390/// default allocator):
391/// @code
392/// /// This class implements a very basic stream buffer suitable for use in
393/// /// 'bslx::GenericOutStream' and 'bslx::GenericInStream'.
394/// class MyStreamBuf {
395///
396/// // DATA
397/// bsl::deque<char> d_buffer; // the input and output buffer
398///
399/// private:
400/// // NOT IMPLEMENTED
401/// MyStreamBuf(const MyStreamBuf&);
402/// MyStreamBuf& operator=(const MyStreamBuf&);
403///
404/// public:
405/// // TYPES
406/// struct traits_type {
407/// static int eof() { return -1; }
408/// };
409///
410/// // CREATORS
411///
412/// /// Create an empty stream buffer.
413/// MyStreamBuf();
414///
415/// /// Destroy this object.
416/// ~MyStreamBuf();
417///
418/// // MANIPULATORS
419///
420/// /// Return 0.
421/// int pubsync();
422///
423/// /// Read the next character in this buffer. Return the value of the
424/// // character on success, and `traits_type::eof()` otherwise.
425/// int sbumpc();
426///
427/// /// Peek at the next character in this buffer. Return the value of
428/// /// the character on success, and `traits_type::eof()` otherwise.
429/// int sgetc();
430///
431/// /// Load the specified `length` characters into the specified
432/// /// address `s`, and return the number of characters read.
433/// bsl::streamsize sgetn(char *s, bsl::streamsize length);
434///
435/// /// Write the specified character `c` to this buffer. Return `c` on
436/// /// success, and `traits_type::eof()` otherwise.
437/// int sputc(char c);
438///
439/// /// Write the specified `length` characters at the specified address
440/// /// `s` to this buffer, and return the number of characters written.
441/// bsl::streamsize sputn(const char *s, bsl::streamsize length);
442/// };
443///
444/// // ========================================================================
445/// // INLINE FUNCTION DEFINITIONS
446/// // ========================================================================
447///
448/// // CREATORS
449/// MyStreamBuf::MyStreamBuf()
450/// : d_buffer()
451/// {
452/// }
453///
454/// MyStreamBuf::~MyStreamBuf()
455/// {
456/// }
457///
458/// // MANIPULATORS
459/// int MyStreamBuf::pubsync()
460/// {
461/// // In this implementation, there is nothing to be done except return
462/// // success.
463///
464/// return 0;
465/// }
466///
467/// int MyStreamBuf::sbumpc()
468/// {
469/// if (!d_buffer.empty()) {
470/// const int rv = static_cast<int>(d_buffer.front());
471/// d_buffer.pop_front();
472/// return rv; // RETURN
473/// }
474/// return traits_type::eof();
475/// }
476///
477/// int MyStreamBuf::sgetc()
478/// {
479/// if (!d_buffer.empty()) {
480/// return static_cast<int>(d_buffer.front()); // RETURN
481/// }
482/// return traits_type::eof();
483/// }
484///
485/// bsl::streamsize MyStreamBuf::sgetn(char *s, bsl::streamsize length)
486/// {
487/// for (bsl::streamsize i = 0; i < length; ++i) {
488/// if (d_buffer.empty()) {
489/// return i; // RETURN
490/// }
491/// s[i] = d_buffer.front();
492/// d_buffer.pop_front();
493/// }
494/// return length;
495/// }
496///
497/// int MyStreamBuf::sputc(char c)
498/// {
499/// d_buffer.push_back(c);
500/// return static_cast<int>(c);
501/// }
502///
503/// bsl::streamsize MyStreamBuf::sputn(const char *s,
504/// bsl::streamsize length)
505/// {
506/// for (bsl::streamsize i = 0; i < length; ++i) {
507/// d_buffer.push_back(s[i]);
508/// }
509/// return length;
510/// }
511/// @endcode
512/// Then, we create a `MyPerson` `janeSmith2` and a `bslx::GenericOutStream`
513/// `outStream2`:
514/// @code
515/// MyPerson janeSmith2("Jane", "Smith", 42);
516/// MyStreamBuf buffer2;
517/// bslx::GenericOutStream<MyStreamBuf> outStream2(&buffer2, 20131127);
518/// const int VERSION2 = 1;
519/// outStream2.putVersion(VERSION2);
520/// janeSmith2.bdexStreamOut(outStream2, VERSION2);
521/// assert(outStream2.isValid());
522/// @endcode
523/// Next, create a `MyPerson` `janeCopy2` initialized to the default value, and
524/// assert that `janeCopy2` is different from `janeSmith2`:
525/// @code
526/// MyPerson janeCopy2;
527/// assert(janeCopy2 != janeSmith2);
528/// @endcode
529/// Then, create a `bslx::GenericInStream` `inStream2` initialized with the
530/// buffer from the `bslx::GenericOutStream` object `outStream2` and
531/// unexternalize this data into `janeCopy2`:
532/// @code
533/// bslx::GenericInStream<MyStreamBuf> inStream2(&buffer2);
534/// int version2;
535/// inStream2.getVersion(version2);
536/// janeCopy2.bdexStreamIn(inStream2, version2);
537/// assert(inStream2.isValid());
538/// @endcode
539/// Finally, `assert` the obtained values are as expected:
540/// @code
541/// assert(version2 == VERSION2);
542/// assert(janeCopy2 == janeSmith2);
543/// @endcode
544/// @}
545/** @} */
546/** @} */
547
548/** @addtogroup bsl
549 * @{
550 */
551/** @addtogroup bslx
552 * @{
553 */
554/** @addtogroup bslx_genericinstream
555 * @{
556 */
557
558#include <bslscm_version.h>
559
561
562#include <bsls_assert.h>
563#include <bsls_performancehint.h>
564#include <bsls_platform.h>
565#include <bsls_types.h>
566
567#include <bsl_cstddef.h>
568#include <bsl_string.h>
569#include <bsl_vector.h>
570
571
572namespace bslx {
573
574 // =====================
575 // class GenericInStream
576 // =====================
577
578/// This class provides input methods to unexternalize values, and C-style
579/// arrays of values, of the fundamental integral and floating-point types,
580/// as well as `bsl::string` values, using a byte format documented in the
581/// @ref bslx_byteoutstream component. In particular, each `get` method of
582/// this class is guaranteed to read stream data written by the
583/// corresponding `put` method of `bslx::GenericOutStream`. Note that
584/// attempting to read beyond the end of a stream will automatically
585/// invalidate the stream. See the `bslx` package-level documentation for
586/// the definition of the BDEX `InStream` protocol.
587///
588/// See @ref bslx_genericinstream
589template <class STREAMBUF>
591
592 // PRIVATE TYPES
593 enum {
594 // Enumerate the platform-independent sizes (in bytes) of data types in
595 // wire format. Note that the wire format size may differ from the
596 // size in memory.
597
598 k_SIZEOF_INT64 = 8,
599 k_SIZEOF_INT56 = 7,
600 k_SIZEOF_INT48 = 6,
601 k_SIZEOF_INT40 = 5,
602 k_SIZEOF_INT32 = 4,
603 k_SIZEOF_INT24 = 3,
604 k_SIZEOF_INT16 = 2,
605 k_SIZEOF_INT8 = 1,
606 k_SIZEOF_FLOAT64 = 8,
607 k_SIZEOF_FLOAT32 = 4
608 };
609
610 // DATA
611 STREAMBUF *d_streamBuf; // held stream to read from
612
613 bool d_validFlag; // stream validity flag; 'true' if stream is in
614 // valid state, 'false' otherwise
615
616 // NOT IMPLEMENTED
618 GenericInStream& operator=(const GenericInStream&);
619
620 private:
621 // PRIVATE MANIPULATORS
622
623 /// Put this output stream into a valid state. This function has no
624 /// effect if this stream is already valid.
625 void validate();
626
627 public:
628 // CREATORS
629
630 /// Create an input byte stream that reads its input from the specified
631 /// `streamBuf`.
632 GenericInStream(STREAMBUF *streamBuf);
633
634 /// Destroy this object.
636
637 // MANIPULATORS
638
639 /// If the most-significant bit of the one byte of this stream at the
640 /// current cursor location is set, assign to the specified `length` the
641 /// four-byte, two's complement integer (in host byte order) comprised
642 /// of the four bytes of this stream at the current cursor location (in
643 /// network byte order) with the most-significant bit unset; otherwise,
644 /// assign to `length` the one-byte, two's complement integer comprised
645 /// of the one byte of this stream at the current cursor location.
646 /// Update the cursor location and return a reference to this stream.
647 /// If this stream is initially invalid, this operation has no effect.
648 /// If this function otherwise fails to extract a valid value, this
649 /// stream is marked invalid and the value of `length` is undefined.
650 /// Note that the value will be zero-extended.
651 GenericInStream& getLength(int& length);
652
653 /// Assign to the specified `version` the one-byte, two's complement
654 /// unsigned integer comprised of the one byte of this stream at the
655 /// current cursor location, update the cursor location, and return a
656 /// reference to this stream. If this stream is initially invalid, this
657 /// operation has no effect. If this function otherwise fails to
658 /// extract a valid value, this stream is marked invalid and the value
659 /// of `version` is undefined. Note that the value will be
660 /// zero-extended.
661 GenericInStream& getVersion(int& version);
662
663 /// Put this input stream in an invalid state. This function has no
664 /// effect if this stream is already invalid. Note that this function
665 /// should be called whenever a value extracted from this stream is
666 /// determined to be invalid, inconsistent, or otherwise incorrect.
667 void invalidate();
668
669 // *** scalar integer values ***
670
671 /// Assign to the specified `variable` the eight-byte, two's complement
672 /// integer (in host byte order) comprised of the eight bytes of this
673 /// stream at the current cursor location (in network byte order),
674 /// update the cursor location, and return a reference to this stream.
675 /// If this stream is initially invalid, this operation has no effect.
676 /// If this function otherwise fails to extract a valid value, this
677 /// stream is marked invalid and the value of `variable` is undefined.
678 /// Note that the value will be sign-extended.
680
681 /// Assign to the specified `variable` the eight-byte, two's complement
682 /// unsigned integer (in host byte order) comprised of the eight bytes
683 /// of this stream at the current cursor location (in network byte
684 /// order), update the cursor location, and return a reference to this
685 /// stream. If this stream is initially invalid, this operation has no
686 /// effect. If this function otherwise fails to extract a valid value,
687 /// this stream is marked invalid and the value of `variable` is
688 /// undefined. Note that the value will be zero-extended.
690
691 /// Assign to the specified `variable` the seven-byte, two's complement
692 /// integer (in host byte order) comprised of the seven bytes of this
693 /// stream at the current cursor location (in network byte order),
694 /// update the cursor location, and return a reference to this stream.
695 /// If this stream is initially invalid, this operation has no effect.
696 /// If this function otherwise fails to extract a valid value, this
697 /// stream is marked invalid and the value of `variable` is undefined.
698 /// Note that the value will be sign-extended.
700
701 /// Assign to the specified `variable` the seven-byte, two's complement
702 /// unsigned integer (in host byte order) comprised of the seven bytes
703 /// of this stream at the current cursor location (in network byte
704 /// order), update the cursor location, and return a reference to this
705 /// stream. If this stream is initially invalid, this operation has no
706 /// effect. If this function otherwise fails to extract a valid value,
707 /// this stream is marked invalid and the value of `variable` is
708 /// undefined. Note that the value will be zero-extended.
710
711 /// Assign to the specified `variable` the six-byte, two's complement
712 /// integer (in host byte order) comprised of the six bytes of this
713 /// stream at the current cursor location (in network byte order),
714 /// update the cursor location, and return a reference to this stream.
715 /// If this stream is initially invalid, this operation has no effect.
716 /// If this function otherwise fails to extract a valid value, this
717 /// stream is marked invalid and the value of `variable` is undefined.
718 /// Note that the value will be sign-extended.
720
721 /// Assign to the specified `variable` the six-byte, two's complement
722 /// unsigned integer (in host byte order) comprised of the six bytes of
723 /// this stream at the current cursor location (in network byte order),
724 /// update the cursor location, and return a reference to this stream.
725 /// If this stream is initially invalid, this operation has no effect.
726 /// If this function otherwise fails to extract a valid value, this
727 /// stream is marked invalid and the value of `variable` is undefined.
728 /// Note that the value will be zero-extended.
730
731 /// Assign to the specified `variable` the five-byte, two's complement
732 /// integer (in host byte order) comprised of the five bytes of this
733 /// stream at the current cursor location (in network byte order),
734 /// update the cursor location, and return a reference to this stream.
735 /// If this stream is initially invalid, this operation has no effect.
736 /// If this function otherwise fails to extract a valid value, this
737 /// stream is marked invalid and the value of `variable` is undefined.
738 /// Note that the value will be sign-extended.
740
741 /// Assign to the specified `variable` the five-byte, two's complement
742 /// unsigned integer (in host byte order) comprised of the five bytes of
743 /// this stream at the current cursor location (in network byte order),
744 /// update the cursor location, and return a reference to this stream.
745 /// If this stream is initially invalid, this operation has no effect.
746 /// If this function otherwise fails to extract a valid value, this
747 /// stream is marked invalid and the value of `variable` is undefined.
748 /// Note that the value will be zero-extended.
750
751 /// Assign to the specified `variable` the four-byte, two's complement
752 /// integer (in host byte order) comprised of the four bytes of this
753 /// stream at the current cursor location (in network byte order),
754 /// update the cursor location, and return a reference to this stream.
755 /// If this stream is initially invalid, this operation has no effect.
756 /// If this function otherwise fails to extract a valid value, this
757 /// stream is marked invalid and the value of `variable` is undefined.
758 /// Note that the value will be sign-extended.
759 GenericInStream& getInt32(int& variable);
760
761 /// Assign to the specified `variable` the four-byte, two's complement
762 /// unsigned integer (in host byte order) comprised of the four bytes of
763 /// this stream at the current cursor location (in network byte order),
764 /// update the cursor location, and return a reference to this stream.
765 /// If this stream is initially invalid, this operation has no effect.
766 /// If this function otherwise fails to extract a valid value, this
767 /// stream is marked invalid and the value of `variable` is undefined.
768 /// Note that the value will be zero-extended.
769 GenericInStream& getUint32(unsigned int& variable);
770
771 /// Assign to the specified `variable` the three-byte, two's complement
772 /// integer (in host byte order) comprised of the three bytes of this
773 /// stream at the current cursor location (in network byte order),
774 /// update the cursor location, and return a reference to this stream.
775 /// If this stream is initially invalid, this operation has no effect.
776 /// If this function otherwise fails to extract a valid value, this
777 /// stream is marked invalid and the value of `variable` is undefined.
778 /// Note that the value will be sign-extended.
779 GenericInStream& getInt24(int& variable);
780
781 /// Assign to the specified `variable` the three-byte, two's complement
782 /// unsigned integer (in host byte order) comprised of the three bytes
783 /// of this stream at the current cursor location (in network byte
784 /// order), update the cursor location, and return a reference to this
785 /// stream. If this stream is initially invalid, this operation has no
786 /// effect. If this function otherwise fails to extract a valid value,
787 /// this stream is marked invalid and the value of `variable` is
788 /// undefined. Note that the value will be zero-extended.
789 GenericInStream& getUint24(unsigned int& variable);
790
791 /// Assign to the specified `variable` the two-byte, two's complement
792 /// integer (in host byte order) comprised of the two bytes of this
793 /// stream at the current cursor location (in network byte order),
794 /// update the cursor location, and return a reference to this stream.
795 /// If this stream is initially invalid, this operation has no effect.
796 /// If this function otherwise fails to extract a valid value, this
797 /// stream is marked invalid and the value of `variable` is undefined.
798 /// Note that the value will be sign-extended.
799 GenericInStream& getInt16(short& variable);
800
801 /// Assign to the specified `variable` the two-byte, two's complement
802 /// unsigned integer (in host byte order) comprised of the two bytes of
803 /// this stream at the current cursor location (in network byte order),
804 /// update the cursor location, and return a reference to this stream.
805 /// If this stream is initially invalid, this operation has no effect.
806 /// If this function otherwise fails to extract a valid value, this
807 /// stream is marked invalid and the value of `variable` is undefined.
808 /// Note that the value will be zero-extended.
809 GenericInStream& getUint16(unsigned short& variable);
810
811 /// Assign to the specified `variable` the one-byte, two's complement
812 /// integer comprised of the one byte of this stream at the current
813 /// cursor location, update the cursor location, and return a reference
814 /// to this stream. If this stream is initially invalid, this operation
815 /// has no effect. If this function otherwise fails to extract a valid
816 /// value, this stream is marked invalid and the value of `variable` is
817 /// undefined. Note that the value will be sign-extended.
818 GenericInStream& getInt8(char& variable);
819 GenericInStream& getInt8(signed char& variable);
820
821 /// Assign to the specified `variable` the one-byte, two's complement
822 /// unsigned integer comprised of the one byte of this stream at the
823 /// current cursor location, update the cursor location, and return a
824 /// reference to this stream. If this stream is initially invalid, this
825 /// operation has no effect. If this function otherwise fails to
826 /// extract a valid value, this stream is marked invalid and the value
827 /// of `variable` is undefined. Note that the value will be
828 /// zero-extended.
829 GenericInStream& getUint8(char& variable);
830 GenericInStream& getUint8(unsigned char& variable);
831
832 // *** scalar floating-point values ***
833
834 /// Assign to the specified `variable` the eight-byte IEEE
835 /// double-precision floating-point number (in host byte order)
836 /// comprised of the eight bytes of this stream at the current cursor
837 /// location (in network byte order), update the cursor location, and
838 /// return a reference to this stream. If this stream is initially
839 /// invalid, this operation has no effect. If this function otherwise
840 /// fails to extract a valid value, this stream is marked invalid and
841 /// the value of `variable` is undefined.
842 GenericInStream& getFloat64(double& variable);
843
844 /// Assign to the specified `variable` the four-byte IEEE
845 /// single-precision floating-point number (in host byte order)
846 /// comprised of the four bytes of this stream at the current cursor
847 /// location (in network byte order), update the cursor location, and
848 /// return a reference to this stream. If this stream is initially
849 /// invalid, this operation has no effect. If this function otherwise
850 /// fails to extract a valid value, this stream is marked invalid and
851 /// the value of `variable` is undefined.
852 GenericInStream& getFloat32(float& variable);
853
854 // *** string values ***
855
856 /// Assign to the specified `variable` the string comprised of the
857 /// length of the string (see `getLength`) and the string data (see
858 /// `getUint8`), update the cursor location, and return a reference to
859 /// this stream. If this stream is initially invalid, this operation
860 /// has no effect. If this function otherwise fails to extract a valid
861 /// value, this stream is marked invalid and the value of `variable` is
862 /// undefined.
864
865 // *** arrays of integer values ***
866
867 /// Assign to the specified `variables` the consecutive eight-byte,
868 /// two's complement integers (in host byte order) comprised of each of
869 /// the specified `numVariables` eight-byte sequences of this stream at
870 /// the current cursor location (in network byte order), update the
871 /// cursor location, and return a reference to this stream. If this
872 /// stream is initially invalid, this operation has no effect. If this
873 /// function otherwise fails to extract a valid value, this stream is
874 /// marked invalid and the value of `variables` is undefined. The
875 /// behavior is undefined unless `0 <= numVariables` and `variables` has
876 /// sufficient capacity. Note that each of the values will be
877 /// sign-extended.
879 int numVariables);
880
881 /// Assign to the specified `variables` the consecutive eight-byte,
882 /// two's complement unsigned integers (in host byte order) comprised of
883 /// each of the specified `numVariables` eight-byte sequences of this
884 /// stream at the current cursor location (in network byte order),
885 /// update the cursor location, and return a reference to this stream.
886 /// If this stream is initially invalid, this operation has no effect.
887 /// If this function otherwise fails to extract a valid value, this
888 /// stream is marked invalid and the value of `variables` is undefined.
889 /// The behavior is undefined unless `0 <= numVariables` and `variables`
890 /// has sufficient capacity. Note that each of the values will be
891 /// zero-extended.
893 int numVariables);
894
895 /// Assign to the specified `variables` the consecutive seven-byte,
896 /// two's complement integers (in host byte order) comprised of each of
897 /// the specified `numVariables` seven-byte sequences of this stream at
898 /// the current cursor location (in network byte order), update the
899 /// cursor location, and return a reference to this stream. If this
900 /// stream is initially invalid, this operation has no effect. If this
901 /// function otherwise fails to extract a valid value, this stream is
902 /// marked invalid and the value of `variables` is undefined. The
903 /// behavior is undefined unless `0 <= numVariables` and `variables` has
904 /// sufficient capacity. Note that each of the values will be
905 /// sign-extended.
907 int numVariables);
908
909 /// Assign to the specified `variables` the consecutive seven-byte,
910 /// two's complement unsigned integers (in host byte order) comprised of
911 /// each of the specified `numVariables` seven-byte sequences of this
912 /// stream at the current cursor location (in network byte order),
913 /// update the cursor location, and return a reference to this stream.
914 /// If this stream is initially invalid, this operation has no effect.
915 /// If this function otherwise fails to extract a valid value, this
916 /// stream is marked invalid and the value of `variables` is undefined.
917 /// The behavior is undefined unless `0 <= numVariables` and `variables`
918 /// has sufficient capacity. Note that each of the values will be
919 /// zero-extended.
921 int numVariables);
922
923 /// Assign to the specified `variables` the consecutive six-byte, two's
924 /// complement integers (in host byte order) comprised of each of the
925 /// specified `numVariables` six-byte sequences of this stream at the
926 /// current cursor location (in network byte order), update the cursor
927 /// location, and return a reference to this stream. If this stream is
928 /// initially invalid, this operation has no effect. If this function
929 /// otherwise fails to extract a valid value, this stream is marked
930 /// invalid and the value of `variables` is undefined. The behavior is
931 /// undefined unless `0 <= numVariables` and `variables` has sufficient
932 /// capacity. Note that each of the values will be sign-extended.
934 int numVariables);
935
936 /// Assign to the specified `variables` the consecutive six-byte, two's
937 /// complement unsigned integers (in host byte order) comprised of each
938 /// of the specified `numVariables` six-byte sequences of this stream at
939 /// the current cursor location (in network byte order), update the
940 /// cursor location, and return a reference to this stream. If this
941 /// stream is initially invalid, this operation has no effect. If this
942 /// function otherwise fails to extract a valid value, this stream is
943 /// marked invalid and the value of `variables` is undefined. The
944 /// behavior is undefined unless `0 <= numVariables` and `variables` has
945 /// sufficient capacity. Note that each of the values will be
946 /// zero-extended.
948 int numVariables);
949
950 /// Assign to the specified `variables` the consecutive five-byte, two's
951 /// complement integers (in host byte order) comprised of each of the
952 /// specified `numVariables` five-byte sequences of this stream at the
953 /// current cursor location (in network byte order), update the cursor
954 /// location, and return a reference to this stream. If this stream is
955 /// initially invalid, this operation has no effect. If this function
956 /// otherwise fails to extract a valid value, this stream is marked
957 /// invalid and the value of `variables` is undefined. The behavior is
958 /// undefined unless `0 <= numVariables` and `variables` has sufficient
959 /// capacity. Note that each of the values will be sign-extended.
961 int numVariables);
962
963 /// Assign to the specified `variables` the consecutive five-byte, two's
964 /// complement unsigned integers (in host byte order) comprised of each
965 /// of the specified `numVariables` five-byte sequences of this stream
966 /// at the current cursor location (in network byte order), update the
967 /// cursor location, and return a reference to this stream. If this
968 /// stream is initially invalid, this operation has no effect. If this
969 /// function otherwise fails to extract a valid value, this stream is
970 /// marked invalid and the value of `variables` is undefined. The
971 /// behavior is undefined unless `0 <= numVariables` and `variables` has
972 /// sufficient capacity. Note that each of the values will be
973 /// zero-extended.
975 int numVariables);
976
977 /// Assign to the specified `variables` the consecutive four-byte, two's
978 /// complement integers (in host byte order) comprised of each of the
979 /// specified `numVariables` four-byte sequences of this stream at the
980 /// current cursor location (in network byte order), update the cursor
981 /// location, and return a reference to this stream. If this stream is
982 /// initially invalid, this operation has no effect. If this function
983 /// otherwise fails to extract a valid value, this stream is marked
984 /// invalid and the value of `variables` is undefined. The behavior is
985 /// undefined unless `0 <= numVariables` and `variables` has sufficient
986 /// capacity. Note that each of the values will be sign-extended.
987 GenericInStream& getArrayInt32(int *variables, int numVariables);
988
989 /// Assign to the specified `variables` the consecutive four-byte, two's
990 /// complement unsigned integers (in host byte order) comprised of each
991 /// of the specified `numVariables` four-byte sequences of this stream
992 /// at the current cursor location (in network byte order), update the
993 /// cursor location, and return a reference to this stream. If this
994 /// stream is initially invalid, this operation has no effect. If this
995 /// function otherwise fails to extract a valid value, this stream is
996 /// marked invalid and the value of `variables` is undefined. The
997 /// behavior is undefined unless `0 <= numVariables` and `variables` has
998 /// sufficient capacity. Note that each of the values will be
999 /// zero-extended.
1000 GenericInStream& getArrayUint32(unsigned int *variables, int numVariables);
1001
1002 /// Assign to the specified `variables` the consecutive three-byte,
1003 /// two's complement integers (in host byte order) comprised of each of
1004 /// the specified `numVariables` three-byte sequences of this stream at
1005 /// the current cursor location (in network byte order), update the
1006 /// cursor location, and return a reference to this stream. If this
1007 /// stream is initially invalid, this operation has no effect. If this
1008 /// function otherwise fails to extract a valid value, this stream is
1009 /// marked invalid and the value of `variables` is undefined. The
1010 /// behavior is undefined unless `0 <= numValues` and `variables` has
1011 /// sufficient capacity. Note that each of the values will be
1012 /// sign-extended.
1013 GenericInStream& getArrayInt24(int *variables, int numVariables);
1014
1015 /// Assign to the specified `variables` the consecutive three-byte,
1016 /// two's complement unsigned integers (in host byte order) comprised of
1017 /// each of the specified `numVariables` three-byte sequences of this
1018 /// stream at the current cursor location (in network byte order),
1019 /// update the cursor location, and return a reference to this stream.
1020 /// If this stream is initially invalid, this operation has no effect.
1021 /// If this function otherwise fails to extract a valid value, this
1022 /// stream is marked invalid and the value of `variables` is undefined.
1023 /// The behavior is undefined unless `0 <= numVariables` and `variables`
1024 /// has sufficient capacity. Note that each of the values will be
1025 /// zero-extended.
1026 GenericInStream& getArrayUint24(unsigned int *variables, int numVariables);
1027
1028 /// Assign to the specified `variables` the consecutive two-byte, two's
1029 /// complement integers (in host byte order) comprised of each of the
1030 /// specified `numVariables` two-byte sequences of this stream at the
1031 /// current cursor location (in network byte order), update the cursor
1032 /// location, and return a reference to this stream. If this stream is
1033 /// initially invalid, this operation has no effect. If this function
1034 /// otherwise fails to extract a valid value, this stream is marked
1035 /// invalid and the value of `variables` is undefined. The behavior is
1036 /// undefined unless `0 <= numVariables` and `variables` has sufficient
1037 /// capacity. Note that each of the values will be sign-extended.
1038 GenericInStream& getArrayInt16(short *variables, int numVariables);
1039
1040 /// Assign to the specified `variables` the consecutive two-byte, two's
1041 /// complement unsigned integers (in host byte order) comprised of each
1042 /// of the specified `numVariables` two-byte sequences of this stream at
1043 /// the current cursor location (in network byte order), update the
1044 /// cursor location, and return a reference to this stream. If this
1045 /// stream is initially invalid, this operation has no effect. If this
1046 /// function otherwise fails to extract a valid value, this stream is
1047 /// marked invalid and the value of `variables` is undefined. The
1048 /// behavior is undefined unless `0 <= numVariables` and `variables` has
1049 /// sufficient capacity. Note that each of the values will be
1050 /// zero-extended.
1051 GenericInStream& getArrayUint16(unsigned short *variables,
1052 int numVariables);
1053
1054 /// Assign to the specified `variables` the consecutive one-byte, two's
1055 /// complement integers comprised of each of the specified
1056 /// `numVariables` one-byte sequences of this stream at the current
1057 /// cursor location, update the cursor location, and return a reference
1058 /// to this stream. If this stream is initially invalid, this operation
1059 /// has no effect. If this function otherwise fails to extract a valid
1060 /// value, this stream is marked invalid and the value of `variables` is
1061 /// undefined. The behavior is undefined unless `0 <= numVariables` and
1062 /// `variables` has sufficient capacity. Note that each of the values
1063 /// will be sign-extended.
1064 GenericInStream& getArrayInt8(char *variables, int numVariables);
1065 GenericInStream& getArrayInt8(signed char *variables, int numVariables);
1066
1067 /// Assign to the specified `variables` the consecutive one-byte, two's
1068 /// complement unsigned integers comprised of each of the specified
1069 /// `numVariables` one-byte sequences of this stream at the current
1070 /// cursor location, update the cursor location, and return a reference
1071 /// to this stream. If this stream is initially invalid, this operation
1072 /// has no effect. If this function otherwise fails to extract a valid
1073 /// value, this stream is marked invalid and the value of `variables` is
1074 /// undefined. The behavior is undefined unless `0 <= numVariables` and
1075 /// `variables` has sufficient capacity. Note that each of the values
1076 /// will be zero-extended.
1077 GenericInStream& getArrayUint8(char *variables, int numVariables);
1078 GenericInStream& getArrayUint8(unsigned char *variables, int numVariables);
1079
1080 // *** arrays of floating-point values ***
1081
1082 /// Assign to the specified `variables` the consecutive eight-byte IEEE
1083 /// double-precision floating-point numbers (in host byte order)
1084 /// comprised of each of the specified `numVariables` eight-byte
1085 /// sequences of this stream at the current cursor location (in network
1086 /// byte order), update the cursor location, and return a reference to
1087 /// this stream. If this stream is initially invalid, this operation
1088 /// has no effect. If this function otherwise fails to extract a valid
1089 /// value, this stream is marked invalid and the value of `variables` is
1090 /// undefined. The behavior is undefined unless `0 <= numVariables` and
1091 /// `variables` has sufficient capacity.
1092 GenericInStream& getArrayFloat64(double *variables, int numVariables);
1093
1094 /// Assign to the specified `variables` the consecutive four-byte IEEE
1095 /// single-precision floating-point numbers (in host byte order)
1096 /// comprised of each of the specified `numVariables` four-byte
1097 /// sequences of this stream at the current cursor location (in network
1098 /// byte order), update the cursor location, and return a reference to
1099 /// this stream. If this stream is initially invalid, this operation
1100 /// has no effect. If this function otherwise fails to extract a valid
1101 /// value, this stream is marked invalid and the value of `variables` is
1102 /// undefined. The behavior is undefined unless `0 <= numVariables` and
1103 /// `variables` has sufficient capacity.
1104 GenericInStream& getArrayFloat32(float *variables, int numVariables);
1105
1106 // ACCESSORS
1107
1108 /// Return a non-zero value if this stream is valid, and 0 otherwise.
1109 /// An invalid stream is a stream in which insufficient or invalid data
1110 /// was detected during an extraction operation. Note that an empty
1111 /// stream will be valid unless an extraction attempt or explicit
1112 /// invalidation causes it to be otherwise.
1113 operator const void *() const;
1114
1115 /// Return `true` if this stream is valid, and `false` otherwise. An
1116 /// invalid stream is a stream in which insufficient or invalid data was
1117 /// detected during an extraction operation. Note that an empty stream
1118 /// will be valid unless an extraction attempt or explicit invalidation
1119 /// causes it to be otherwise.
1120 bool isValid() const;
1121};
1122
1123// FREE OPERATORS
1124
1125/// Read the specified `value` from the specified input `stream` following
1126/// the requirements of the BDEX protocol (see the `bslx` package-level
1127/// documentation), and return a reference to `stream`. The behavior is
1128/// undefined unless `TYPE` is BDEX-compliant.
1129template <class STREAMBUF, class TYPE>
1131 operator>>(GenericInStream<STREAMBUF>& stream, TYPE& value);
1132
1133// ============================================================================
1134// INLINE DEFINITIONS
1135// ============================================================================
1136
1137 // ---------------------
1138 // class GenericInStream
1139 // ---------------------
1140
1141// PRIVATE MANIPULATORS
1142template <class STREAMBUF>
1143inline
1145{
1146 d_validFlag = true;
1147}
1148
1149// CREATORS
1150template <class STREAMBUF>
1151inline
1153: d_streamBuf(streamBuf)
1154, d_validFlag(true)
1155{
1156 BSLS_ASSERT_SAFE(streamBuf);
1157}
1158
1159template <class STREAMBUF>
1160inline
1164
1165// MANIPULATORS
1166template <class STREAMBUF>
1167inline
1169{
1170 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1172 return *this; // RETURN
1173 }
1174
1175 invalidate();
1176
1177 const int current = d_streamBuf->sgetc();
1178 if (STREAMBUF::traits_type::eof() != current) {
1179 validate();
1180 if (127 < current) {
1181 // If 'length > 127', 'length' is stored as 4 bytes with top bit
1182 // set.
1183
1184 getInt32(length);
1185 length &= 0x7fffffff; // Clear top bit.
1186 }
1187 else {
1188 // If 'length <= 127', 'length' is stored as one byte.
1189
1190 char tmp = 0;
1191 getInt8(tmp);
1192 length = tmp;
1193 }
1194 }
1195
1196 return *this;
1197}
1198
1199template <class STREAMBUF>
1200inline
1203{
1204 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1206 return *this; // RETURN
1207 }
1208
1209 unsigned char tmp = 0;
1210 getUint8(tmp);
1211 version = tmp;
1212
1213 return *this;
1214}
1215
1216template <class STREAMBUF>
1217inline
1219{
1220 d_validFlag = false;
1221}
1222
1223 // *** scalar integer values ***
1224
1225template <class STREAMBUF>
1226inline
1229{
1230 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1232 return *this; // RETURN
1233 }
1234
1235 invalidate();
1236
1237 if (sizeof variable > k_SIZEOF_INT64) {
1238 const int current = d_streamBuf->sgetc();
1240 STREAMBUF::traits_type::eof() == current)) {
1242 return *this; // RETURN
1243 }
1244 variable = 0x80 & current ? -1 : 0; // sign extend
1245 }
1246
1247#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1248 char *bytes = reinterpret_cast<char *>(&variable);
1249 char rawBytes[k_SIZEOF_INT64];
1250 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT64)) {
1251 validate();
1252 bytes[7] = rawBytes[0];
1253 bytes[6] = rawBytes[1];
1254 bytes[5] = rawBytes[2];
1255 bytes[4] = rawBytes[3];
1256 bytes[3] = rawBytes[4];
1257 bytes[2] = rawBytes[5];
1258 bytes[1] = rawBytes[6];
1259 bytes[0] = rawBytes[7];
1260 }
1261#else
1262 char *bytes =
1263 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT64;
1264 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT64)) {
1265 validate();
1266 }
1267#endif
1268
1269 return *this;
1270}
1271
1272template <class STREAMBUF>
1273inline
1276{
1277 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1279 return *this; // RETURN
1280 }
1281
1282 invalidate();
1283
1284 if (sizeof variable > k_SIZEOF_INT64) {
1285 variable = 0; // zero-extend
1286 }
1287
1288#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1289 char *bytes = reinterpret_cast<char *>(&variable);
1290 char rawBytes[k_SIZEOF_INT64];
1291 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT64)) {
1292 validate();
1293 bytes[7] = rawBytes[0];
1294 bytes[6] = rawBytes[1];
1295 bytes[5] = rawBytes[2];
1296 bytes[4] = rawBytes[3];
1297 bytes[3] = rawBytes[4];
1298 bytes[2] = rawBytes[5];
1299 bytes[1] = rawBytes[6];
1300 bytes[0] = rawBytes[7];
1301 }
1302#else
1303 char *bytes =
1304 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT64;
1305 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT64)) {
1306 validate();
1307 }
1308#endif
1309
1310 return *this;
1311}
1312
1313template <class STREAMBUF>
1314inline
1317{
1318 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1320 return *this; // RETURN
1321 }
1322
1323 invalidate();
1324
1325 const int current = d_streamBuf->sgetc();
1327 STREAMBUF::traits_type::eof() == current)) {
1329 return *this; // RETURN
1330 }
1331 variable = 0x80 & current ? -1 : 0; // sign extend
1332
1333#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1334 char *bytes = reinterpret_cast<char *>(&variable);
1335 char rawBytes[k_SIZEOF_INT56];
1336 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT56)) {
1337 validate();
1338 bytes[6] = rawBytes[0];
1339 bytes[5] = rawBytes[1];
1340 bytes[4] = rawBytes[2];
1341 bytes[3] = rawBytes[3];
1342 bytes[2] = rawBytes[4];
1343 bytes[1] = rawBytes[5];
1344 bytes[0] = rawBytes[6];
1345 }
1346#else
1347 char *bytes =
1348 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT56;
1349 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT56)) {
1350 validate();
1351 }
1352#endif
1353
1354 return *this;
1355}
1356
1357template <class STREAMBUF>
1358inline
1361{
1362 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1364 return *this; // RETURN
1365 }
1366
1367 invalidate();
1368
1369 variable = 0; // zero-extend
1370
1371#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1372 char *bytes = reinterpret_cast<char *>(&variable);
1373 char rawBytes[k_SIZEOF_INT56];
1374 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT56)) {
1375 validate();
1376 bytes[6] = rawBytes[0];
1377 bytes[5] = rawBytes[1];
1378 bytes[4] = rawBytes[2];
1379 bytes[3] = rawBytes[3];
1380 bytes[2] = rawBytes[4];
1381 bytes[1] = rawBytes[5];
1382 bytes[0] = rawBytes[6];
1383 }
1384#else
1385 char *bytes =
1386 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT56;
1387 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT56)) {
1388 validate();
1389 }
1390#endif
1391
1392 return *this;
1393}
1394
1395template <class STREAMBUF>
1396inline
1399{
1400 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1402 return *this; // RETURN
1403 }
1404
1405 invalidate();
1406
1407 const int current = d_streamBuf->sgetc();
1409 STREAMBUF::traits_type::eof() == current)) {
1411 return *this; // RETURN
1412 }
1413 variable = 0x80 & current ? -1 : 0; // sign extend
1414
1415#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1416 char *bytes = reinterpret_cast<char *>(&variable);
1417 char rawBytes[k_SIZEOF_INT48];
1418 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT48)) {
1419 validate();
1420 bytes[5] = rawBytes[0];
1421 bytes[4] = rawBytes[1];
1422 bytes[3] = rawBytes[2];
1423 bytes[2] = rawBytes[3];
1424 bytes[1] = rawBytes[4];
1425 bytes[0] = rawBytes[5];
1426 }
1427#else
1428 char *bytes =
1429 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT48;
1430 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT48)) {
1431 validate();
1432 }
1433#endif
1434
1435 return *this;
1436}
1437
1438template <class STREAMBUF>
1439inline
1442{
1443 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1445 return *this; // RETURN
1446 }
1447
1448 invalidate();
1449
1450 variable = 0; // zero-extend
1451
1452#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1453 char *bytes = reinterpret_cast<char *>(&variable);
1454 char rawBytes[k_SIZEOF_INT48];
1455 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT48)) {
1456 validate();
1457 bytes[5] = rawBytes[0];
1458 bytes[4] = rawBytes[1];
1459 bytes[3] = rawBytes[2];
1460 bytes[2] = rawBytes[3];
1461 bytes[1] = rawBytes[4];
1462 bytes[0] = rawBytes[5];
1463 }
1464#else
1465 char *bytes =
1466 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT48;
1467 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT48)) {
1468 validate();
1469 }
1470#endif
1471
1472 return *this;
1473}
1474
1475template <class STREAMBUF>
1476inline
1479{
1480 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1482 return *this; // RETURN
1483 }
1484
1485 invalidate();
1486
1487 const int current = d_streamBuf->sgetc();
1489 STREAMBUF::traits_type::eof() == current)) {
1491 return *this; // RETURN
1492 }
1493 variable = 0x80 & current ? -1 : 0; // sign extend
1494
1495#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1496 char *bytes = reinterpret_cast<char *>(&variable);
1497 char rawBytes[k_SIZEOF_INT40];
1498 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT40)) {
1499 validate();
1500 bytes[4] = rawBytes[0];
1501 bytes[3] = rawBytes[1];
1502 bytes[2] = rawBytes[2];
1503 bytes[1] = rawBytes[3];
1504 bytes[0] = rawBytes[4];
1505 }
1506#else
1507 char *bytes =
1508 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT40;
1509 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT40)) {
1510 validate();
1511 }
1512#endif
1513
1514 return *this;
1515}
1516
1517template <class STREAMBUF>
1518inline
1521{
1522 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1524 return *this; // RETURN
1525 }
1526
1527 invalidate();
1528
1529 variable = 0; // zero-extend
1530
1531#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1532 char *bytes = reinterpret_cast<char *>(&variable);
1533 char rawBytes[k_SIZEOF_INT40];
1534 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT40)) {
1535 validate();
1536 bytes[4] = rawBytes[0];
1537 bytes[3] = rawBytes[1];
1538 bytes[2] = rawBytes[2];
1539 bytes[1] = rawBytes[3];
1540 bytes[0] = rawBytes[4];
1541 }
1542#else
1543 char *bytes =
1544 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT40;
1545 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT40)) {
1546 validate();
1547 }
1548#endif
1549
1550 return *this;
1551}
1552
1553template <class STREAMBUF>
1554inline
1557{
1558 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1560 return *this; // RETURN
1561 }
1562
1563 invalidate();
1564
1565 if (sizeof variable > k_SIZEOF_INT32) {
1566 const int current = d_streamBuf->sgetc();
1568 STREAMBUF::traits_type::eof() == current)) {
1570 return *this; // RETURN
1571 }
1572 variable = 0x80 & current ? -1 : 0; // sign extend
1573 }
1574
1575#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1576 char *bytes = reinterpret_cast<char *>(&variable);
1577 char rawBytes[k_SIZEOF_INT32];
1578 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT32)) {
1579 validate();
1580 bytes[3] = rawBytes[0];
1581 bytes[2] = rawBytes[1];
1582 bytes[1] = rawBytes[2];
1583 bytes[0] = rawBytes[3];
1584 }
1585#else
1586 char *bytes =
1587 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT32;
1588 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT32)) {
1589 validate();
1590 }
1591#endif
1592
1593 return *this;
1594}
1595
1596template <class STREAMBUF>
1597inline
1600{
1601 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1603 return *this; // RETURN
1604 }
1605
1606 invalidate();
1607
1608 if (sizeof variable > k_SIZEOF_INT32) {
1609 variable = 0; // zero-extend
1610 }
1611
1612#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1613 char *bytes = reinterpret_cast<char *>(&variable);
1614 char rawBytes[k_SIZEOF_INT32];
1615 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT32)) {
1616 validate();
1617 bytes[3] = rawBytes[0];
1618 bytes[2] = rawBytes[1];
1619 bytes[1] = rawBytes[2];
1620 bytes[0] = rawBytes[3];
1621 }
1622#else
1623 char *bytes =
1624 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT32;
1625 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT32)) {
1626 validate();
1627 }
1628#endif
1629
1630 return *this;
1631}
1632
1633template <class STREAMBUF>
1634inline
1637{
1638 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1640 return *this; // RETURN
1641 }
1642
1643 invalidate();
1644
1645 const int current = d_streamBuf->sgetc();
1647 STREAMBUF::traits_type::eof() == current)) {
1649 return *this; // RETURN
1650 }
1651 variable = 0x80 & current ? -1 : 0; // sign extend
1652
1653#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1654 char *bytes = reinterpret_cast<char *>(&variable);
1655 char rawBytes[k_SIZEOF_INT24];
1656 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT24)) {
1657 validate();
1658 bytes[2] = rawBytes[0];
1659 bytes[1] = rawBytes[1];
1660 bytes[0] = rawBytes[2];
1661 }
1662#else
1663 char *bytes =
1664 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT24;
1665 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT24)) {
1666 validate();
1667 }
1668#endif
1669
1670 return *this;
1671}
1672
1673template <class STREAMBUF>
1674inline
1677{
1678 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1680 return *this; // RETURN
1681 }
1682
1683 invalidate();
1684
1685 variable = 0; // zero-extend
1686
1687#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1688 char *bytes = reinterpret_cast<char *>(&variable);
1689 char rawBytes[k_SIZEOF_INT24];
1690 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT24)) {
1691 validate();
1692 bytes[2] = rawBytes[0];
1693 bytes[1] = rawBytes[1];
1694 bytes[0] = rawBytes[2];
1695 }
1696#else
1697 char *bytes =
1698 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT24;
1699 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT24)) {
1700 validate();
1701 }
1702#endif
1703
1704 return *this;
1705}
1706
1707template <class STREAMBUF>
1708inline
1711{
1712 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1714 return *this; // RETURN
1715 }
1716
1717 invalidate();
1718
1719 if (sizeof variable > k_SIZEOF_INT16) {
1720 const int current = d_streamBuf->sgetc();
1722 STREAMBUF::traits_type::eof() == current)) {
1724 return *this; // RETURN
1725 }
1726 variable = 0x80 & current ? -1 : 0; // sign extend
1727 }
1728
1729#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1730 char *bytes = reinterpret_cast<char *>(&variable);
1731 char rawBytes[k_SIZEOF_INT16];
1732 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT16)) {
1733 validate();
1734 bytes[1] = rawBytes[0];
1735 bytes[0] = rawBytes[1];
1736 }
1737#else
1738 char *bytes =
1739 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT16;
1740 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT16)) {
1741 validate();
1742 }
1743#endif
1744
1745 return *this;
1746}
1747
1748template <class STREAMBUF>
1749inline
1752{
1753 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1755 return *this; // RETURN
1756 }
1757
1758 invalidate();
1759
1760 if (sizeof variable > k_SIZEOF_INT16) {
1761 variable = 0; // zero-extend
1762 }
1763
1764#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1765 char *bytes = reinterpret_cast<char *>(&variable);
1766 char rawBytes[k_SIZEOF_INT16];
1767 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT16)) {
1768 validate();
1769 bytes[1] = rawBytes[0];
1770 bytes[0] = rawBytes[1];
1771 }
1772#else
1773 char *bytes =
1774 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT16;
1775 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT16)) {
1776 validate();
1777 }
1778#endif
1779
1780 return *this;
1781}
1782
1783template <class STREAMBUF>
1784inline
1787{
1788 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1790 return *this; // RETURN
1791 }
1792
1793 invalidate();
1794
1795 const int current = d_streamBuf->sbumpc();
1796 if (STREAMBUF::traits_type::eof() != current) {
1797 validate();
1798 variable = static_cast<char>(current);
1799 }
1800
1801 return *this;
1802}
1803
1804template <class STREAMBUF>
1805inline
1808{
1809 return getInt8(reinterpret_cast<char&>(variable));
1810}
1811
1812template <class STREAMBUF>
1813inline
1816{
1817 return getInt8(variable);
1818}
1819
1820template <class STREAMBUF>
1821inline
1824{
1825 return getInt8(reinterpret_cast<char&>(variable));
1826}
1827
1828 // *** scalar floating-point values ***
1829
1830template <class STREAMBUF>
1831inline
1834{
1835 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1837 return *this; // RETURN
1838 }
1839
1840 invalidate();
1841
1842 if (sizeof variable > k_SIZEOF_FLOAT64) {
1843 variable = 0; // zero-fill mantissa
1844 }
1845
1846#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1847 char *bytes = reinterpret_cast<char *>(&variable);
1848 char rawBytes[k_SIZEOF_FLOAT64];
1849 if (k_SIZEOF_FLOAT64 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_FLOAT64)) {
1850 validate();
1851 bytes[sizeof variable - 1] = rawBytes[0];
1852 bytes[sizeof variable - 2] = rawBytes[1];
1853 bytes[sizeof variable - 3] = rawBytes[2];
1854 bytes[sizeof variable - 4] = rawBytes[3];
1855 bytes[sizeof variable - 5] = rawBytes[4];
1856 bytes[sizeof variable - 6] = rawBytes[5];
1857 bytes[sizeof variable - 7] = rawBytes[6];
1858 bytes[sizeof variable - 8] = rawBytes[7];
1859 }
1860#else
1861 char *bytes = reinterpret_cast<char *>(&variable);
1862 if (k_SIZEOF_FLOAT64 == d_streamBuf->sgetn(bytes, k_SIZEOF_FLOAT64)) {
1863 validate();
1864 }
1865#endif
1866
1867 return *this;
1868}
1869
1870template <class STREAMBUF>
1871inline
1874{
1875 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1877 return *this; // RETURN
1878 }
1879
1880 invalidate();
1881
1882 if (sizeof variable > k_SIZEOF_FLOAT32) {
1883 variable = 0; // zero-fill mantissa
1884 }
1885
1886#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1887 char *bytes = reinterpret_cast<char *>(&variable);
1888 char rawBytes[k_SIZEOF_FLOAT32];
1889 if (k_SIZEOF_FLOAT32 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_FLOAT32)) {
1890 validate();
1891 bytes[sizeof variable - 1] = rawBytes[0];
1892 bytes[sizeof variable - 2] = rawBytes[1];
1893 bytes[sizeof variable - 3] = rawBytes[2];
1894 bytes[sizeof variable - 4] = rawBytes[3];
1895 }
1896#else
1897 char *bytes = reinterpret_cast<char *>(&variable);
1898 if (k_SIZEOF_FLOAT32 == d_streamBuf->sgetn(bytes, k_SIZEOF_FLOAT32)) {
1899 validate();
1900 }
1901#endif
1902
1903 return *this;
1904}
1905
1906 // *** string values ***
1907
1908template <class STREAMBUF>
1911{
1912 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1914 return *this; // RETURN
1915 }
1916
1917 int length = 0;
1918 getLength(length);
1919
1920 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1922 return *this; // RETURN
1923 }
1924
1925 // 'length' could be corrupt or invalid, so we limit the initial 'resize'
1926 // to something that can accommodate the preponderance of strings that will
1927 // arise in practice. The remaining portion of a string longer than 16M is
1928 // read in via a second pass.
1929
1930 enum { k_INITIAL_ALLOCATION_SIZE = 16 * 1024 * 1024 };
1931
1932 const int initialLength = length < k_INITIAL_ALLOCATION_SIZE
1933 ? length
1934 : k_INITIAL_ALLOCATION_SIZE;
1935
1936 variable.resize(initialLength);
1937
1938 if (0 == length) {
1939 return *this; // RETURN
1940 }
1941
1942 getArrayUint8(&variable.front(), initialLength);
1943 if (isValid() && length > initialLength) {
1944 variable.resize(length);
1945 getArrayUint8(&variable[initialLength], length - initialLength);
1946 }
1947
1948 return *this;
1949}
1950
1951 // *** arrays of integer values ***
1952
1953template <class STREAMBUF>
1956 int numVariables)
1957{
1958 BSLS_ASSERT(variables);
1959 BSLS_ASSERT(0 <= numVariables);
1960
1962 || 0 == numVariables)) {
1964 return *this; // RETURN
1965 }
1966
1967 const bsls::Types::Int64 *end = variables + numVariables;
1968 for (; variables != end; ++variables) {
1969 getInt64(*variables);
1970 }
1971
1972 return *this;
1973}
1974
1975template <class STREAMBUF>
1978 int numVariables)
1979{
1980 BSLS_ASSERT(variables);
1981 BSLS_ASSERT(0 <= numVariables);
1982
1984 || 0 == numVariables)) {
1986 return *this; // RETURN
1987 }
1988
1989 const bsls::Types::Uint64 *end = variables + numVariables;
1990 for (; variables != end; ++variables) {
1991 getUint64(*variables);
1992 }
1993
1994 return *this;
1995}
1996
1997template <class STREAMBUF>
2000 int numVariables)
2001{
2002 BSLS_ASSERT(variables);
2003 BSLS_ASSERT(0 <= numVariables);
2004
2006 || 0 == numVariables)) {
2008 return *this; // RETURN
2009 }
2010
2011 const bsls::Types::Int64 *end = variables + numVariables;
2012 for (; variables != end; ++variables) {
2013 getInt56(*variables);
2014 }
2015
2016 return *this;
2017}
2018
2019template <class STREAMBUF>
2022 int numVariables)
2023{
2024 BSLS_ASSERT(variables);
2025 BSLS_ASSERT(0 <= numVariables);
2026
2028 || 0 == numVariables)) {
2030 return *this; // RETURN
2031 }
2032
2033 const bsls::Types::Uint64 *end = variables + numVariables;
2034 for (; variables != end; ++variables) {
2035 getUint56(*variables);
2036 }
2037
2038 return *this;
2039}
2040
2041template <class STREAMBUF>
2044 int numVariables)
2045{
2046 BSLS_ASSERT(variables);
2047 BSLS_ASSERT(0 <= numVariables);
2048
2050 || 0 == numVariables)) {
2052 return *this; // RETURN
2053 }
2054
2055 const bsls::Types::Int64 *end = variables + numVariables;
2056 for (; variables != end; ++variables) {
2057 getInt48(*variables);
2058 }
2059
2060 return *this;
2061}
2062
2063template <class STREAMBUF>
2066 int numVariables)
2067{
2068 BSLS_ASSERT(variables);
2069 BSLS_ASSERT(0 <= numVariables);
2070
2072 || 0 == numVariables)) {
2074 return *this; // RETURN
2075 }
2076
2077 const bsls::Types::Uint64 *end = variables + numVariables;
2078 for (; variables != end; ++variables) {
2079 getUint48(*variables);
2080 }
2081
2082 return *this;
2083}
2084
2085template <class STREAMBUF>
2088 int numVariables)
2089{
2090 BSLS_ASSERT(variables);
2091 BSLS_ASSERT(0 <= numVariables);
2092
2094 || 0 == numVariables)) {
2096 return *this; // RETURN
2097 }
2098
2099 const bsls::Types::Int64 *end = variables + numVariables;
2100 for (; variables != end; ++variables) {
2101 getInt40(*variables);
2102 }
2103
2104 return *this;
2105}
2106
2107template <class STREAMBUF>
2110 int numVariables)
2111{
2112 BSLS_ASSERT(variables);
2113 BSLS_ASSERT(0 <= numVariables);
2114
2116 || 0 == numVariables)) {
2118 return *this; // RETURN
2119 }
2120
2121 const bsls::Types::Uint64 *end = variables + numVariables;
2122 for (; variables != end; ++variables) {
2123 getUint40(*variables);
2124 }
2125
2126 return *this;
2127}
2128
2129template <class STREAMBUF>
2131GenericInStream<STREAMBUF>::getArrayInt32(int *variables, int numVariables)
2132{
2133 BSLS_ASSERT(variables);
2134 BSLS_ASSERT(0 <= numVariables);
2135
2137 || 0 == numVariables)) {
2139 return *this; // RETURN
2140 }
2141
2142 const int *end = variables + numVariables;
2143 for (; variables != end; ++variables) {
2144 getInt32(*variables);
2145 }
2146
2147 return *this;
2148}
2149
2150template <class STREAMBUF>
2153 int numVariables)
2154{
2155 BSLS_ASSERT(variables);
2156 BSLS_ASSERT(0 <= numVariables);
2157
2159 || 0 == numVariables)) {
2161 return *this; // RETURN
2162 }
2163
2164 const unsigned int *end = variables + numVariables;
2165 for (; variables != end; ++variables) {
2166 getUint32(*variables);
2167 }
2168
2169 return *this;
2170}
2171
2172template <class STREAMBUF>
2174GenericInStream<STREAMBUF>::getArrayInt24(int *variables, int numVariables)
2175{
2176 BSLS_ASSERT(variables);
2177 BSLS_ASSERT(0 <= numVariables);
2178
2180 || 0 == numVariables)) {
2182 return *this; // RETURN
2183 }
2184
2185 const int *end = variables + numVariables;
2186 for (; variables != end; ++variables) {
2187 getInt24(*variables);
2188 }
2189
2190 return *this;
2191}
2192
2193template <class STREAMBUF>
2196 int numVariables)
2197{
2198 BSLS_ASSERT(variables);
2199 BSLS_ASSERT(0 <= numVariables);
2200
2202 || 0 == numVariables)) {
2204 return *this; // RETURN
2205 }
2206
2207 const unsigned int *end = variables + numVariables;
2208 for (; variables != end; ++variables) {
2209 getUint24(*variables);
2210 }
2211
2212 return *this;
2213}
2214
2215template <class STREAMBUF>
2218 int numVariables)
2219{
2220 BSLS_ASSERT(variables);
2221 BSLS_ASSERT(0 <= numVariables);
2222
2224 || 0 == numVariables)) {
2226 return *this; // RETURN
2227 }
2228
2229 const short *end = variables + numVariables;
2230 for (; variables != end; ++variables) {
2231 getInt16(*variables);
2232 }
2233
2234 return *this;
2235}
2236
2237template <class STREAMBUF>
2240 int numVariables)
2241{
2242 BSLS_ASSERT(variables);
2243 BSLS_ASSERT(0 <= numVariables);
2244
2246 || 0 == numVariables)) {
2248 return *this; // RETURN
2249 }
2250
2251 const unsigned short *end = variables + numVariables;
2252 for (; variables != end; ++variables) {
2253 getUint16(*variables);
2254 }
2255
2256 return *this;
2257}
2258
2259template <class STREAMBUF>
2262 int numVariables)
2263{
2264 BSLS_ASSERT(variables);
2265 BSLS_ASSERT(0 <= numVariables);
2266
2268 || 0 == numVariables)) {
2270 return *this; // RETURN
2271 }
2272
2273 const char *end = variables + numVariables;
2274 for (; variables != end; ++variables) {
2275 getInt8(*variables);
2276 }
2277
2278 return *this;
2279}
2280
2281template <class STREAMBUF>
2282inline
2285 int numVariables)
2286{
2287 BSLS_ASSERT_SAFE(variables);
2288 BSLS_ASSERT_SAFE(0 <= numVariables);
2289
2290 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
2291}
2292
2293template <class STREAMBUF>
2294inline
2297 int numVariables)
2298{
2299 BSLS_ASSERT_SAFE(variables);
2300 BSLS_ASSERT_SAFE(0 <= numVariables);
2301
2302 return getArrayInt8(variables, numVariables);
2303}
2304
2305template <class STREAMBUF>
2306inline
2309 int numVariables)
2310{
2311 BSLS_ASSERT_SAFE(variables);
2312 BSLS_ASSERT_SAFE(0 <= numVariables);
2313
2314 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
2315}
2316
2317 // *** arrays of floating-point values ***
2318
2319template <class STREAMBUF>
2322 int numVariables)
2323{
2324 BSLS_ASSERT(variables);
2325 BSLS_ASSERT(0 <= numVariables);
2326
2328 || 0 == numVariables)) {
2330 return *this; // RETURN
2331 }
2332
2333 const double *end = variables + numVariables;
2334 for (; variables != end; ++variables) {
2335 getFloat64(*variables);
2336 }
2337
2338 return *this;
2339}
2340
2341template <class STREAMBUF>
2344 int numVariables)
2345{
2346 BSLS_ASSERT(variables);
2347 BSLS_ASSERT(0 <= numVariables);
2348
2350 || 0 == numVariables)) {
2352 return *this; // RETURN
2353 }
2354
2355 const float *end = variables + numVariables;
2356 for (; variables != end; ++variables) {
2357 getFloat32(*variables);
2358 }
2359
2360 return *this;
2361}
2362
2363// ACCESSORS
2364template <class STREAMBUF>
2365inline
2367{
2368 return isValid() ? this : 0;
2369}
2370
2371template <class STREAMBUF>
2372inline
2374{
2375 return d_validFlag;
2376}
2377
2378template <class STREAMBUF, class TYPE>
2379inline
2382{
2383 return InStreamFunctions::bdexStreamIn(stream, value);
2384}
2385
2386} // close package namespace
2387
2388
2389#endif
2390
2391// ----------------------------------------------------------------------------
2392// Copyright 2014 Bloomberg Finance L.P.
2393//
2394// Licensed under the Apache License, Version 2.0 (the "License");
2395// you may not use this file except in compliance with the License.
2396// You may obtain a copy of the License at
2397//
2398// http://www.apache.org/licenses/LICENSE-2.0
2399//
2400// Unless required by applicable law or agreed to in writing, software
2401// distributed under the License is distributed on an "AS IS" BASIS,
2402// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2403// See the License for the specific language governing permissions and
2404// limitations under the License.
2405// ----------------------------- END-OF-FILE ----------------------------------
2406
2407/** @} */
2408/** @} */
2409/** @} */
Definition bslstl_string.h:1281
CHAR_TYPE & front()
Definition bslstl_string.h:5502
void resize(size_type newLength, CHAR_TYPE character)
Definition bslstl_string.h:5364
Definition bslx_genericinstream.h:590
GenericInStream & getInt16(short &variable)
Definition bslx_genericinstream.h:1710
GenericInStream & getArrayUint32(unsigned int *variables, int numVariables)
Definition bslx_genericinstream.h:2152
GenericInStream & getArrayInt40(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:2087
GenericInStream & getInt8(char &variable)
Definition bslx_genericinstream.h:1786
GenericInStream & getArrayUint16(unsigned short *variables, int numVariables)
Definition bslx_genericinstream.h:2239
GenericInStream & getArrayInt56(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:1999
GenericInStream & getUint16(unsigned short &variable)
Definition bslx_genericinstream.h:1751
~GenericInStream()
Destroy this object.
Definition bslx_genericinstream.h:1161
GenericInStream & getArrayFloat32(float *variables, int numVariables)
Definition bslx_genericinstream.h:2343
GenericInStream & getUint32(unsigned int &variable)
Definition bslx_genericinstream.h:1599
GenericInStream & getArrayInt32(int *variables, int numVariables)
Definition bslx_genericinstream.h:2131
GenericInStream & getInt48(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1398
GenericInStream & getArrayUint24(unsigned int *variables, int numVariables)
Definition bslx_genericinstream.h:2195
void invalidate()
Definition bslx_genericinstream.h:1218
GenericInStream & getFloat64(double &variable)
Definition bslx_genericinstream.h:1833
bool isValid() const
Definition bslx_genericinstream.h:2373
GenericInStream & getArrayFloat64(double *variables, int numVariables)
Definition bslx_genericinstream.h:2321
GenericInStream & getUint64(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1275
GenericInStream & getInt32(int &variable)
Definition bslx_genericinstream.h:1556
GenericInStream & getArrayInt24(int *variables, int numVariables)
Definition bslx_genericinstream.h:2174
GenericInStream & getUint56(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1360
GenericInStream & getInt56(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1316
GenericInStream & getUint24(unsigned int &variable)
Definition bslx_genericinstream.h:1676
GenericInStream & getArrayInt48(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:2043
GenericInStream & getArrayUint48(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:2065
GenericInStream & getInt64(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1228
GenericInStream & getVersion(int &version)
Definition bslx_genericinstream.h:1202
GenericInStream & getUint8(char &variable)
Definition bslx_genericinstream.h:1815
GenericInStream & getArrayUint8(char *variables, int numVariables)
Definition bslx_genericinstream.h:2296
GenericInStream & getLength(int &length)
Definition bslx_genericinstream.h:1168
GenericInStream & getString(bsl::string &variable)
Definition bslx_genericinstream.h:1910
GenericInStream & getArrayInt16(short *variables, int numVariables)
Definition bslx_genericinstream.h:2217
GenericInStream & getFloat32(float &variable)
Definition bslx_genericinstream.h:1873
GenericInStream & getUint48(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1441
GenericInStream & getArrayInt64(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:1955
GenericInStream & getInt24(int &variable)
Definition bslx_genericinstream.h:1636
GenericInStream & getArrayUint40(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:2109
GenericInStream & getUint40(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1520
GenericInStream & getArrayInt8(char *variables, int numVariables)
Definition bslx_genericinstream.h:2261
GenericInStream & getArrayUint56(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:2021
GenericInStream & getInt40(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1478
GenericInStream & getArrayUint64(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:1977
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
STREAM & bdexStreamIn(STREAM &stream, VALUE_TYPE &variable)
Definition bslx_instreamfunctions.h:1247
Definition bslx_byteinstream.h:377
ByteInStream & operator>>(ByteInStream &stream, TYPE &value)
Definition bslx_byteinstream.h:1986
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132