BDE 4.39.x 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`.
584///
585/// \note Note that attempting to read beyond the end of a stream will automatically
586/// invalidate the stream. See the `bslx` package-level documentation for
587/// the definition of the BDEX `InStream` protocol.
588///
589/// See @ref bslx_genericinstream
590template <class STREAMBUF>
592
593 // PRIVATE TYPES
594 enum {
595 // Enumerate the platform-independent sizes (in bytes) of data types in
596 // wire format. Note that the wire format size may differ from the
597 // size in memory.
598
599 k_SIZEOF_INT64 = 8,
600 k_SIZEOF_INT56 = 7,
601 k_SIZEOF_INT48 = 6,
602 k_SIZEOF_INT40 = 5,
603 k_SIZEOF_INT32 = 4,
604 k_SIZEOF_INT24 = 3,
605 k_SIZEOF_INT16 = 2,
606 k_SIZEOF_INT8 = 1,
607 k_SIZEOF_FLOAT64 = 8,
608 k_SIZEOF_FLOAT32 = 4
609 };
610
611 // DATA
612 STREAMBUF *d_streamBuf; // held stream to read from
613
614 bool d_validFlag; // stream validity flag; 'true' if stream is in
615 // valid state, 'false' otherwise
616
617 private:
618 // NOT IMPLEMENTED
620 GenericInStream& operator=(const GenericInStream&);
621
622 private:
623 // PRIVATE MANIPULATORS
624
625 /// Put this output stream into a valid state. This function has no
626 /// effect if this stream is already valid.
627 void validate();
628
629 public:
630 // CREATORS
631
632 /// Create an input byte stream that reads its input from the specified
633 /// `streamBuf`.
634 GenericInStream(STREAMBUF *streamBuf);
635
636 /// Destroy this object.
638
639 // MANIPULATORS
640
641 /// If the most-significant bit of the one byte of this stream at the
642 /// current cursor location is set, assign to the specified `length` the
643 /// four-byte, two's complement integer (in host byte order) comprised
644 /// of the four bytes of this stream at the current cursor location (in
645 /// network byte order) with the most-significant bit unset; otherwise,
646 /// assign to `length` the one-byte, two's complement integer comprised
647 /// of the one byte of this stream at the current cursor location.
648 /// Update the cursor location and return a reference to this stream.
649 /// If this stream is initially invalid, this operation has no effect.
650 /// If this function otherwise fails to extract a valid value, this
651 /// stream is marked invalid and the value of `length` is undefined.
652 ///
653 /// \note Note that the value will be zero-extended.
654 GenericInStream& getLength(int& length);
655
656 /// Assign to the specified `version` the one-byte, two's complement
657 /// unsigned integer comprised of the one byte of this stream at the
658 /// current cursor location, update the cursor location, and return a
659 /// reference to this stream. If this stream is initially invalid, this
660 /// operation has no effect. If this function otherwise fails to
661 /// extract a valid value, this stream is marked invalid and the value of `version` is undefined.
662 ///
663 /// \note Note that the value will be
664 /// zero-extended.
665 GenericInStream& getVersion(int& version);
666
667 /// Put this input stream in an invalid state. This function has no effect if this stream is already invalid.
668 ///
669 /// \note Note that this function
670 /// should be called whenever a value extracted from this stream is
671 /// determined to be invalid, inconsistent, or otherwise incorrect.
672 void invalidate();
673
674 // *** scalar integer values ***
675
676 /// Assign to the specified `variable` the eight-byte, two's complement
677 /// integer (in host byte order) comprised of the eight bytes of this
678 /// stream at the current cursor location (in network byte order),
679 /// update the cursor location, and return a reference to this stream.
680 /// If this stream is initially invalid, this operation has no effect.
681 /// If this function otherwise fails to extract a valid value, this
682 /// stream is marked invalid and the value of `variable` is undefined.
683 ///
684 /// \note Note that the value will be sign-extended.
686
687 /// Assign to the specified `variable` the eight-byte, two's complement
688 /// unsigned integer (in host byte order) comprised of the eight bytes
689 /// of this stream at the current cursor location (in network byte
690 /// order), update the cursor location, and return a reference to this
691 /// stream. If this stream is initially invalid, this operation has no
692 /// effect. If this function otherwise fails to extract a valid value,
693 /// this stream is marked invalid and the value of `variable` is undefined.
694 ///
695 /// \note Note that the value will be zero-extended.
697
698 /// Assign to the specified `variable` the seven-byte, two's complement
699 /// integer (in host byte order) comprised of the seven bytes of this
700 /// stream at the current cursor location (in network byte order),
701 /// update the cursor location, and return a reference to this stream.
702 /// If this stream is initially invalid, this operation has no effect.
703 /// If this function otherwise fails to extract a valid value, this
704 /// stream is marked invalid and the value of `variable` is undefined.
705 ///
706 /// \note Note that the value will be sign-extended.
708
709 /// Assign to the specified `variable` the seven-byte, two's complement
710 /// unsigned integer (in host byte order) comprised of the seven bytes
711 /// of this stream at the current cursor location (in network byte
712 /// order), update the cursor location, and return a reference to this
713 /// stream. If this stream is initially invalid, this operation has no
714 /// effect. If this function otherwise fails to extract a valid value,
715 /// this stream is marked invalid and the value of `variable` is undefined.
716 ///
717 /// \note Note that the value will be zero-extended.
719
720 /// Assign to the specified `variable` the six-byte, two's complement
721 /// integer (in host byte order) comprised of the six bytes of this
722 /// stream at the current cursor location (in network byte order),
723 /// update the cursor location, and return a reference to this stream.
724 /// If this stream is initially invalid, this operation has no effect.
725 /// If this function otherwise fails to extract a valid value, this
726 /// stream is marked invalid and the value of `variable` is undefined.
727 ///
728 /// \note Note that the value will be sign-extended.
730
731 /// Assign to the specified `variable` the six-byte, two's complement
732 /// unsigned integer (in host byte order) comprised of the six bytes of
733 /// this 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 ///
739 /// \note Note that the value will be zero-extended.
741
742 /// Assign to the specified `variable` the five-byte, two's complement
743 /// integer (in host byte order) comprised of the five bytes of this
744 /// stream at the current cursor location (in network byte order),
745 /// update the cursor location, and return a reference to this stream.
746 /// If this stream is initially invalid, this operation has no effect.
747 /// If this function otherwise fails to extract a valid value, this
748 /// stream is marked invalid and the value of `variable` is undefined.
749 ///
750 /// \note Note that the value will be sign-extended.
752
753 /// Assign to the specified `variable` the five-byte, two's complement
754 /// unsigned integer (in host byte order) comprised of the five bytes of
755 /// this stream at the current cursor location (in network byte order),
756 /// update the cursor location, and return a reference to this stream.
757 /// If this stream is initially invalid, this operation has no effect.
758 /// If this function otherwise fails to extract a valid value, this
759 /// stream is marked invalid and the value of `variable` is undefined.
760 ///
761 /// \note Note that the value will be zero-extended.
763
764 /// Assign to the specified `variable` the four-byte, two's complement
765 /// integer (in host byte order) comprised of the four bytes of this
766 /// stream at the current cursor location (in network byte order),
767 /// update the cursor location, and return a reference to this stream.
768 /// If this stream is initially invalid, this operation has no effect.
769 /// If this function otherwise fails to extract a valid value, this
770 /// stream is marked invalid and the value of `variable` is undefined.
771 ///
772 /// \note Note that the value will be sign-extended.
773 GenericInStream& getInt32(int& variable);
774
775 /// Assign to the specified `variable` the four-byte, two's complement
776 /// unsigned integer (in host byte order) comprised of the four bytes of
777 /// this stream at the current cursor location (in network byte order),
778 /// update the cursor location, and return a reference to this stream.
779 /// If this stream is initially invalid, this operation has no effect.
780 /// If this function otherwise fails to extract a valid value, this
781 /// stream is marked invalid and the value of `variable` is undefined.
782 ///
783 /// \note Note that the value will be zero-extended.
784 GenericInStream& getUint32(unsigned int& variable);
785
786 /// Assign to the specified `variable` the three-byte, two's complement
787 /// integer (in host byte order) comprised of the three bytes of this
788 /// stream at the current cursor location (in network byte order),
789 /// update the cursor location, and return a reference to this stream.
790 /// If this stream is initially invalid, this operation has no effect.
791 /// If this function otherwise fails to extract a valid value, this
792 /// stream is marked invalid and the value of `variable` is undefined.
793 ///
794 /// \note Note that the value will be sign-extended.
795 GenericInStream& getInt24(int& variable);
796
797 /// Assign to the specified `variable` the three-byte, two's complement
798 /// unsigned integer (in host byte order) comprised of the three bytes
799 /// of this stream at the current cursor location (in network byte
800 /// order), update the cursor location, and return a reference to this
801 /// stream. If this stream is initially invalid, this operation has no
802 /// effect. If this function otherwise fails to extract a valid value,
803 /// this stream is marked invalid and the value of `variable` is undefined.
804 ///
805 /// \note Note that the value will be zero-extended.
806 GenericInStream& getUint24(unsigned int& variable);
807
808 /// Assign to the specified `variable` the two-byte, two's complement
809 /// integer (in host byte order) comprised of the two bytes of this
810 /// stream at the current cursor location (in network byte order),
811 /// update the cursor location, and return a reference to this stream.
812 /// If this stream is initially invalid, this operation has no effect.
813 /// If this function otherwise fails to extract a valid value, this
814 /// stream is marked invalid and the value of `variable` is undefined.
815 ///
816 /// \note Note that the value will be sign-extended.
817 GenericInStream& getInt16(short& variable);
818
819 /// Assign to the specified `variable` the two-byte, two's complement
820 /// unsigned integer (in host byte order) comprised of the two bytes of
821 /// this stream at the current cursor location (in network byte order),
822 /// update the cursor location, and return a reference to this stream.
823 /// If this stream is initially invalid, this operation has no effect.
824 /// If this function otherwise fails to extract a valid value, this
825 /// stream is marked invalid and the value of `variable` is undefined.
826 ///
827 /// \note Note that the value will be zero-extended.
828 GenericInStream& getUint16(unsigned short& variable);
829
830 /// Assign to the specified `variable` the one-byte, two's complement
831 /// integer comprised of the one byte of this stream at the current
832 /// cursor location, update the cursor location, and return a reference
833 /// to this stream. If this stream is initially invalid, this operation
834 /// has no effect. If this function otherwise fails to extract a valid
835 /// value, this stream is marked invalid and the value of `variable` is undefined.
836 ///
837 /// \note Note that the value will be sign-extended.
838 GenericInStream& getInt8(char& variable);
839 GenericInStream& getInt8(signed char& variable);
840
841 /// Assign to the specified `variable` the one-byte, two's complement
842 /// unsigned integer comprised of the one byte of this stream at the
843 /// current cursor location, update the cursor location, and return a
844 /// reference to this stream. If this stream is initially invalid, this
845 /// operation has no effect. If this function otherwise fails to
846 /// extract a valid value, this stream is marked invalid and the value of `variable` is undefined.
847 ///
848 /// \note Note that the value will be
849 /// zero-extended.
850 GenericInStream& getUint8(char& variable);
851 GenericInStream& getUint8(unsigned char& variable);
852
853 // *** scalar floating-point values ***
854
855 /// Assign to the specified `variable` the eight-byte IEEE
856 /// double-precision floating-point number (in host byte order)
857 /// comprised of the eight bytes of this stream at the current cursor
858 /// location (in network byte order), update the cursor location, and
859 /// return a reference to this stream. If this stream is initially
860 /// invalid, this operation has no effect. If this function otherwise
861 /// fails to extract a valid value, this stream is marked invalid and
862 /// the value of `variable` is undefined.
863 GenericInStream& getFloat64(double& variable);
864
865 /// Assign to the specified `variable` the four-byte IEEE
866 /// single-precision floating-point number (in host byte order)
867 /// comprised of the four bytes of this stream at the current cursor
868 /// location (in network byte order), update the cursor location, and
869 /// return a reference to this stream. If this stream is initially
870 /// invalid, this operation has no effect. If this function otherwise
871 /// fails to extract a valid value, this stream is marked invalid and
872 /// the value of `variable` is undefined.
873 GenericInStream& getFloat32(float& variable);
874
875 // *** string values ***
876
877 /// Assign to the specified `variable` the string comprised of the
878 /// length of the string (see `getLength`) and the string data (see
879 /// `getUint8`), update the cursor location, and return a reference to
880 /// this stream. If this stream is initially invalid, this operation
881 /// has no effect. If this function otherwise fails to extract a valid
882 /// value, this stream is marked invalid and the value of `variable` is
883 /// undefined.
885
886 // *** arrays of integer values ***
887
888 /// Assign to the specified `variables` the consecutive eight-byte,
889 /// two's complement integers (in host byte order) comprised of each of
890 /// the specified `numVariables` eight-byte sequences of this stream at
891 /// the current cursor location (in network byte order), update the
892 /// cursor location, and return a reference to this stream. If this
893 /// stream is initially invalid, this operation has no effect. If this
894 /// function otherwise fails to extract a valid value, this stream is
895 /// marked invalid and the value of `variables` is undefined.
896 ///
897 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has
898 /// sufficient capacity, or `0 == numVariables && nullptr == variables`.
899 ///
900 /// \note Note that each of the values will be sign-extended.
902 int numVariables);
903
904 /// Assign to the specified `variables` the consecutive eight-byte,
905 /// two's complement unsigned integers (in host byte order) comprised of
906 /// each of the specified `numVariables` eight-byte sequences of this
907 /// stream at the current cursor location (in network byte order),
908 /// update the cursor location, and return a reference to this stream.
909 /// If this stream is initially invalid, this operation has no effect.
910 /// If this function otherwise fails to extract a valid value, this
911 /// stream is marked invalid and the value of `variables` is undefined.
912 ///
913 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
914 /// has sufficient capacity, or `0 == numVariables && nullptr == variables`.
915 ///
916 /// \note Note that each of the values will be zero-extended.
918 int numVariables);
919
920 /// Assign to the specified `variables` the consecutive seven-byte,
921 /// two's complement integers (in host byte order) comprised of each of
922 /// the specified `numVariables` seven-byte sequences of this stream at
923 /// the current cursor location (in network byte order), update the
924 /// cursor location, and return a reference to this stream. If this
925 /// stream is initially invalid, this operation has no effect. If this
926 /// function otherwise fails to extract a valid value, this stream is
927 /// marked invalid and the value of `variables` is undefined.
928 ///
929 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has
930 /// sufficient capacity, or `0 == numVariables && nullptr == variables`.
931 ///
932 /// \note Note that each of the values will be sign-extended.
934 int numVariables);
935
936 /// Assign to the specified `variables` the consecutive seven-byte,
937 /// two's complement unsigned integers (in host byte order) comprised of
938 /// each of the specified `numVariables` seven-byte sequences of this
939 /// stream at the current cursor location (in network byte order),
940 /// update the cursor location, and return a reference to this stream.
941 /// If this stream is initially invalid, this operation has no effect.
942 /// If this function otherwise fails to extract a valid value, this
943 /// stream is marked invalid and the value of `variables` is undefined.
944 ///
945 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
946 /// has sufficient capacity, or `0 == numVariables && nullptr == variables`.
947 /// zero-extended.
949 int numVariables);
950
951 /// Assign to the specified `variables` the consecutive six-byte, two's
952 /// complement integers (in host byte order) comprised of each of the
953 /// specified `numVariables` six-byte sequences of this stream at the
954 /// current cursor location (in network byte order), update the cursor
955 /// location, and return a reference to this stream. If this stream is
956 /// initially invalid, this operation has no effect. If this function
957 /// otherwise fails to extract a valid value, this stream is marked
958 /// invalid and the value of `variables` is undefined.
959 ///
960 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient
961 /// capacity, or `0 == numVariables && nullptr == variables`.
962 ///
963 /// \note Note that each of the values will be sign-extended.
965 int numVariables);
966
967 /// Assign to the specified `variables` the consecutive six-byte, two's
968 /// complement unsigned integers (in host byte order) comprised of each
969 /// of the specified `numVariables` six-byte sequences of this stream at
970 /// the current cursor location (in network byte order), update the
971 /// cursor location, and return a reference to this stream. If this
972 /// stream is initially invalid, this operation has no effect. If this
973 /// function otherwise fails to extract a valid value, this stream is
974 /// marked invalid and the value of `variables` is undefined.
975 ///
976 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has
977 /// sufficient capacity, or `0 == numVariables && nullptr == variables`.
978 ///
979 /// \note Note that each of the values will be zero-extended.
981 int numVariables);
982
983 /// Assign to the specified `variables` the consecutive five-byte, two's
984 /// complement integers (in host byte order) comprised of each of the
985 /// specified `numVariables` five-byte sequences of this stream at the
986 /// current cursor location (in network byte order), update the cursor
987 /// location, and return a reference to this stream. If this stream is
988 /// initially invalid, this operation has no effect. If this function
989 /// otherwise fails to extract a valid value, this stream is marked
990 /// invalid and the value of `variables` is undefined.
991 ///
992 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient
993 /// capacity, or `0 == numVariables && nullptr == variables`.
994 ///
995 /// \note Note that each of the values will be sign-extended.
997 int numVariables);
998
999 /// Assign to the specified `variables` the consecutive five-byte, two's
1000 /// complement unsigned integers (in host byte order) comprised of each
1001 /// of the specified `numVariables` five-byte sequences of this stream
1002 /// at the current cursor location (in network byte order), update the
1003 /// cursor location, and return a reference to this stream. If this
1004 /// stream is initially invalid, this operation has no effect. If this
1005 /// function otherwise fails to extract a valid value, this stream is
1006 /// marked invalid and the value of `variables` is undefined.
1007 ///
1008 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has
1009 /// sufficient capacity, or `0 == numVariables && nullptr == variables`.
1010 ///
1011 /// \note Note that each of the values will be zero-extended.
1013 int numVariables);
1014
1015 /// Assign to the specified `variables` the consecutive four-byte, two's
1016 /// complement integers (in host byte order) comprised of each of the
1017 /// specified `numVariables` four-byte sequences of this stream at the
1018 /// current cursor location (in network byte order), update the cursor
1019 /// location, and return a reference to this stream. If this stream is
1020 /// initially invalid, this operation has no effect. If this function
1021 /// otherwise fails to extract a valid value, this stream is marked
1022 /// invalid and the value of `variables` is undefined.
1023 ///
1024 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient
1025 /// capacity, or `0 == numVariables && nullptr == variables`.
1026 ///
1027 /// \note Note that each of the values will be sign-extended.
1028 GenericInStream& getArrayInt32(int *variables, int numVariables);
1029
1030 /// Assign to the specified `variables` the consecutive four-byte, two's
1031 /// complement unsigned integers (in host byte order) comprised of each
1032 /// of the specified `numVariables` four-byte sequences of this stream
1033 /// at the current cursor location (in network byte order), update the
1034 /// cursor location, and return a reference to this stream. If this
1035 /// stream is initially invalid, this operation has no effect. If this
1036 /// function otherwise fails to extract a valid value, this stream is
1037 /// marked invalid and the value of `variables` is undefined.
1038 ///
1039 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has
1040 /// sufficient capacity, or `0 == numVariables && nullptr == variables`.
1041 ///
1042 /// \note Note that each of the values will be zero-extended.
1043 GenericInStream& getArrayUint32(unsigned int *variables, int numVariables);
1044
1045 /// Assign to the specified `variables` the consecutive three-byte,
1046 /// two's complement integers (in host byte order) comprised of each of
1047 /// the specified `numVariables` three-byte sequences of this stream at
1048 /// the current cursor location (in network byte order), update the
1049 /// cursor location, and return a reference to this stream. If this
1050 /// stream is initially invalid, this operation has no effect. If this
1051 /// function otherwise fails to extract a valid value, this stream is
1052 /// marked invalid and the value of `variables` is undefined.
1053 ///
1054 /// \pre The behavior is undefined unless `0 <= numValues` and `variables` has
1055 /// sufficient capacity, or `0 == numVariables && nullptr == variables`.
1056 ///
1057 /// \note Note that each of the values will be sign-extended.
1058 GenericInStream& getArrayInt24(int *variables, int numVariables);
1059
1060 /// Assign to the specified `variables` the consecutive three-byte,
1061 /// two's complement unsigned integers (in host byte order) comprised of
1062 /// each of the specified `numVariables` three-byte sequences of this
1063 /// stream at the current cursor location (in network byte order),
1064 /// update the cursor location, and return a reference to this stream.
1065 /// If this stream is initially invalid, this operation has no effect.
1066 /// If this function otherwise fails to extract a valid value, this
1067 /// stream is marked invalid and the value of `variables` is undefined.
1068 ///
1069 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
1070 /// has sufficient capacity, or `0 == numVariables && nullptr == variables`.
1071 ///
1072 /// \note Note that each of the values will be zero-extended.
1073 GenericInStream& getArrayUint24(unsigned int *variables, int numVariables);
1074
1075 /// Assign to the specified `variables` the consecutive two-byte, two's
1076 /// complement integers (in host byte order) comprised of each of the
1077 /// specified `numVariables` two-byte sequences of this stream at the
1078 /// current cursor location (in network byte order), update the cursor
1079 /// location, and return a reference to this stream. If this stream is
1080 /// initially invalid, this operation has no effect. If this function
1081 /// otherwise fails to extract a valid value, this stream is marked
1082 /// invalid and the value of `variables` is undefined.
1083 ///
1084 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient
1085 /// capacity, or `0 == numVariables && nullptr == variables`.
1086 ///
1087 /// \note Note that each of the values will be sign-extended.
1088 GenericInStream& getArrayInt16(short *variables, int numVariables);
1089
1090 /// Assign to the specified `variables` the consecutive two-byte, two's
1091 /// complement unsigned integers (in host byte order) comprised of each
1092 /// of the specified `numVariables` two-byte sequences of this stream at
1093 /// the current cursor location (in network byte order), update the
1094 /// cursor location, and return a reference to this stream. If this
1095 /// stream is initially invalid, this operation has no effect. If this
1096 /// function otherwise fails to extract a valid value, this stream is
1097 /// marked invalid and the value of `variables` is undefined.
1098 ///
1099 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has
1100 /// sufficient capacity, or `0 == numVariables && nullptr == variables`.
1101 ///
1102 /// \note Note that each of the values will be zero-extended.
1103 GenericInStream& getArrayUint16(unsigned short *variables,
1104 int numVariables);
1105
1106 /// Assign to the specified `variables` the consecutive one-byte, two's
1107 /// complement integers comprised of each of the specified
1108 /// `numVariables` one-byte sequences of this stream at the current
1109 /// cursor location, update the cursor location, and return a reference
1110 /// to this stream. If this stream is initially invalid, this operation
1111 /// has no effect. If this function otherwise fails to extract a valid
1112 /// value, this stream is marked invalid and the value of `variables` is undefined.
1113 ///
1114 /// \pre The behavior is undefined unless `0 <= numVariables` and
1115 /// `variables` has sufficient capacity, or `0 == numVariables && nullptr == variables`.
1116 ///
1117 /// \note Note that each of the values will be sign-extended.
1118 GenericInStream& getArrayInt8(char *variables, int numVariables);
1119 GenericInStream& getArrayInt8(signed char *variables, int numVariables);
1120
1121 /// Assign to the specified `variables` the consecutive one-byte, two's
1122 /// complement unsigned integers comprised of each of the specified
1123 /// `numVariables` one-byte sequences of this stream at the current
1124 /// cursor location, update the cursor location, and return a reference
1125 /// to this stream. If this stream is initially invalid, this operation
1126 /// has no effect. If this function otherwise fails to extract a valid
1127 /// value, this stream is marked invalid and the value of `variables` is undefined.
1128 ///
1129 /// \pre The behavior is undefined unless `0 <= numVariables` and
1130 /// `variables` has sufficient capacity, or `0 == numVariables && nullptr == variables`.
1131 ///
1132 /// \note Note that each of the values will be zero-extended.
1133 GenericInStream& getArrayUint8(char *variables, int numVariables);
1134 GenericInStream& getArrayUint8(unsigned char *variables, int numVariables);
1135
1136 // *** arrays of floating-point values ***
1137
1138 /// Assign to the specified `variables` the consecutive eight-byte IEEE
1139 /// double-precision floating-point numbers (in host byte order)
1140 /// comprised of each of the specified `numVariables` eight-byte
1141 /// sequences of this stream at the current cursor location (in network
1142 /// byte order), update the cursor location, and return a reference to
1143 /// this stream. If this stream is initially invalid, this operation
1144 /// has no effect. If this function otherwise fails to extract a valid
1145 /// value, this stream is marked invalid and the value of `variables` is undefined.
1146 ///
1147 /// \pre The behavior is undefined unless `0 <= numVariables` and
1148 /// `variables` has sufficient capacity.
1149 GenericInStream& getArrayFloat64(double *variables, int numVariables);
1150
1151 /// Assign to the specified `variables` the consecutive four-byte IEEE
1152 /// single-precision floating-point numbers (in host byte order)
1153 /// comprised of each of the specified `numVariables` four-byte
1154 /// sequences of this stream at the current cursor location (in network
1155 /// byte order), update the cursor location, and return a reference to
1156 /// this stream. If this stream is initially invalid, this operation
1157 /// has no effect. If this function otherwise fails to extract a valid
1158 /// value, this stream is marked invalid and the value of `variables` is undefined.
1159 ///
1160 /// \pre The behavior is undefined unless `0 <= numVariables` and
1161 /// `variables` has sufficient capacity.
1162 GenericInStream& getArrayFloat32(float *variables, int numVariables);
1163
1164 // ACCESSORS
1165
1166 /// Return a non-zero value if this stream is valid, and 0 otherwise.
1167 /// An invalid stream is a stream in which insufficient or invalid data was detected during an extraction operation.
1168 ///
1169 /// \note Note that an empty
1170 /// stream will be valid unless an extraction attempt or explicit
1171 /// invalidation causes it to be otherwise.
1172 operator const void *() const;
1173
1174 /// Return `true` if this stream is valid, and `false` otherwise. An
1175 /// invalid stream is a stream in which insufficient or invalid data was detected during an extraction operation.
1176 ///
1177 /// \note Note that an empty stream
1178 /// will be valid unless an extraction attempt or explicit invalidation
1179 /// causes it to be otherwise.
1180 bool isValid() const;
1181};
1182
1183// FREE OPERATORS
1184
1185/// Read the specified `value` from the specified input `stream` following
1186/// the requirements of the BDEX protocol (see the `bslx` package-level
1187/// documentation), and return a reference to `stream`.
1188///
1189/// \pre The behavior is undefined unless `TYPE` is BDEX-compliant.
1190template <class STREAMBUF, class TYPE>
1192 operator>>(GenericInStream<STREAMBUF>& stream, TYPE& value);
1193
1194// ============================================================================
1195// INLINE DEFINITIONS
1196// ============================================================================
1197
1198 // ---------------------
1199 // class GenericInStream
1200 // ---------------------
1201
1202// PRIVATE MANIPULATORS
1203template <class STREAMBUF>
1204inline
1206{
1207 d_validFlag = true;
1208}
1209
1210// CREATORS
1211template <class STREAMBUF>
1212inline
1214: d_streamBuf(streamBuf)
1215, d_validFlag(true)
1216{
1217 BSLS_ASSERT_SAFE(streamBuf);
1218}
1219
1220template <class STREAMBUF>
1221inline
1225
1226// MANIPULATORS
1227template <class STREAMBUF>
1228inline
1230{
1231 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1233 return *this; // RETURN
1234 }
1235
1236 invalidate();
1237
1238 const int current = d_streamBuf->sgetc();
1239 if (STREAMBUF::traits_type::eof() != current) {
1240 validate();
1241 if (127 < current) {
1242 // If 'length > 127', 'length' is stored as 4 bytes with top bit
1243 // set.
1244
1245 getInt32(length);
1246 length &= 0x7fffffff; // Clear top bit.
1247 }
1248 else {
1249 // If 'length <= 127', 'length' is stored as one byte.
1250
1251 char tmp = 0;
1252 getInt8(tmp);
1253 length = tmp;
1254 }
1255 }
1256
1257 return *this;
1258}
1259
1260template <class STREAMBUF>
1261inline
1264{
1265 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1267 return *this; // RETURN
1268 }
1269
1270 unsigned char tmp = 0;
1271 getUint8(tmp);
1272 version = tmp;
1273
1274 return *this;
1275}
1276
1277template <class STREAMBUF>
1278inline
1280{
1281 d_validFlag = false;
1282}
1283
1284 // *** scalar integer values ***
1285
1286template <class STREAMBUF>
1287inline
1290{
1291 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1293 return *this; // RETURN
1294 }
1295
1296 invalidate();
1297
1298 if (sizeof variable > k_SIZEOF_INT64) {
1299 const int current = d_streamBuf->sgetc();
1301 STREAMBUF::traits_type::eof() == current)) {
1303 return *this; // RETURN
1304 }
1305 variable = 0x80 & current ? -1 : 0; // sign extend
1306 }
1307
1308#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1309 char *bytes = reinterpret_cast<char *>(&variable);
1310 char rawBytes[k_SIZEOF_INT64];
1311 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT64)) {
1312 validate();
1313 bytes[7] = rawBytes[0];
1314 bytes[6] = rawBytes[1];
1315 bytes[5] = rawBytes[2];
1316 bytes[4] = rawBytes[3];
1317 bytes[3] = rawBytes[4];
1318 bytes[2] = rawBytes[5];
1319 bytes[1] = rawBytes[6];
1320 bytes[0] = rawBytes[7];
1321 }
1322#else
1323 char *bytes =
1324 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT64;
1325 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT64)) {
1326 validate();
1327 }
1328#endif
1329
1330 return *this;
1331}
1332
1333template <class STREAMBUF>
1334inline
1337{
1338 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1340 return *this; // RETURN
1341 }
1342
1343 invalidate();
1344
1345 if (sizeof variable > k_SIZEOF_INT64) {
1346 variable = 0; // zero-extend
1347 }
1348
1349#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1350 char *bytes = reinterpret_cast<char *>(&variable);
1351 char rawBytes[k_SIZEOF_INT64];
1352 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT64)) {
1353 validate();
1354 bytes[7] = rawBytes[0];
1355 bytes[6] = rawBytes[1];
1356 bytes[5] = rawBytes[2];
1357 bytes[4] = rawBytes[3];
1358 bytes[3] = rawBytes[4];
1359 bytes[2] = rawBytes[5];
1360 bytes[1] = rawBytes[6];
1361 bytes[0] = rawBytes[7];
1362 }
1363#else
1364 char *bytes =
1365 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT64;
1366 if (k_SIZEOF_INT64 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT64)) {
1367 validate();
1368 }
1369#endif
1370
1371 return *this;
1372}
1373
1374template <class STREAMBUF>
1375inline
1378{
1379 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1381 return *this; // RETURN
1382 }
1383
1384 invalidate();
1385
1386 const int current = d_streamBuf->sgetc();
1388 STREAMBUF::traits_type::eof() == current)) {
1390 return *this; // RETURN
1391 }
1392 variable = 0x80 & current ? -1 : 0; // sign extend
1393
1394#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1395 char *bytes = reinterpret_cast<char *>(&variable);
1396 char rawBytes[k_SIZEOF_INT56];
1397 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT56)) {
1398 validate();
1399 bytes[6] = rawBytes[0];
1400 bytes[5] = rawBytes[1];
1401 bytes[4] = rawBytes[2];
1402 bytes[3] = rawBytes[3];
1403 bytes[2] = rawBytes[4];
1404 bytes[1] = rawBytes[5];
1405 bytes[0] = rawBytes[6];
1406 }
1407#else
1408 char *bytes =
1409 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT56;
1410 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT56)) {
1411 validate();
1412 }
1413#endif
1414
1415 return *this;
1416}
1417
1418template <class STREAMBUF>
1419inline
1422{
1423 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1425 return *this; // RETURN
1426 }
1427
1428 invalidate();
1429
1430 variable = 0; // zero-extend
1431
1432#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1433 char *bytes = reinterpret_cast<char *>(&variable);
1434 char rawBytes[k_SIZEOF_INT56];
1435 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT56)) {
1436 validate();
1437 bytes[6] = rawBytes[0];
1438 bytes[5] = rawBytes[1];
1439 bytes[4] = rawBytes[2];
1440 bytes[3] = rawBytes[3];
1441 bytes[2] = rawBytes[4];
1442 bytes[1] = rawBytes[5];
1443 bytes[0] = rawBytes[6];
1444 }
1445#else
1446 char *bytes =
1447 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT56;
1448 if (k_SIZEOF_INT56 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT56)) {
1449 validate();
1450 }
1451#endif
1452
1453 return *this;
1454}
1455
1456template <class STREAMBUF>
1457inline
1460{
1461 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1463 return *this; // RETURN
1464 }
1465
1466 invalidate();
1467
1468 const int current = d_streamBuf->sgetc();
1470 STREAMBUF::traits_type::eof() == current)) {
1472 return *this; // RETURN
1473 }
1474 variable = 0x80 & current ? -1 : 0; // sign extend
1475
1476#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1477 char *bytes = reinterpret_cast<char *>(&variable);
1478 char rawBytes[k_SIZEOF_INT48];
1479 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT48)) {
1480 validate();
1481 bytes[5] = rawBytes[0];
1482 bytes[4] = rawBytes[1];
1483 bytes[3] = rawBytes[2];
1484 bytes[2] = rawBytes[3];
1485 bytes[1] = rawBytes[4];
1486 bytes[0] = rawBytes[5];
1487 }
1488#else
1489 char *bytes =
1490 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT48;
1491 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT48)) {
1492 validate();
1493 }
1494#endif
1495
1496 return *this;
1497}
1498
1499template <class STREAMBUF>
1500inline
1503{
1504 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1506 return *this; // RETURN
1507 }
1508
1509 invalidate();
1510
1511 variable = 0; // zero-extend
1512
1513#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1514 char *bytes = reinterpret_cast<char *>(&variable);
1515 char rawBytes[k_SIZEOF_INT48];
1516 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT48)) {
1517 validate();
1518 bytes[5] = rawBytes[0];
1519 bytes[4] = rawBytes[1];
1520 bytes[3] = rawBytes[2];
1521 bytes[2] = rawBytes[3];
1522 bytes[1] = rawBytes[4];
1523 bytes[0] = rawBytes[5];
1524 }
1525#else
1526 char *bytes =
1527 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT48;
1528 if (k_SIZEOF_INT48 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT48)) {
1529 validate();
1530 }
1531#endif
1532
1533 return *this;
1534}
1535
1536template <class STREAMBUF>
1537inline
1540{
1541 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1543 return *this; // RETURN
1544 }
1545
1546 invalidate();
1547
1548 const int current = d_streamBuf->sgetc();
1550 STREAMBUF::traits_type::eof() == current)) {
1552 return *this; // RETURN
1553 }
1554 variable = 0x80 & current ? -1 : 0; // sign extend
1555
1556#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1557 char *bytes = reinterpret_cast<char *>(&variable);
1558 char rawBytes[k_SIZEOF_INT40];
1559 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT40)) {
1560 validate();
1561 bytes[4] = rawBytes[0];
1562 bytes[3] = rawBytes[1];
1563 bytes[2] = rawBytes[2];
1564 bytes[1] = rawBytes[3];
1565 bytes[0] = rawBytes[4];
1566 }
1567#else
1568 char *bytes =
1569 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT40;
1570 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT40)) {
1571 validate();
1572 }
1573#endif
1574
1575 return *this;
1576}
1577
1578template <class STREAMBUF>
1579inline
1582{
1583 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1585 return *this; // RETURN
1586 }
1587
1588 invalidate();
1589
1590 variable = 0; // zero-extend
1591
1592#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1593 char *bytes = reinterpret_cast<char *>(&variable);
1594 char rawBytes[k_SIZEOF_INT40];
1595 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT40)) {
1596 validate();
1597 bytes[4] = rawBytes[0];
1598 bytes[3] = rawBytes[1];
1599 bytes[2] = rawBytes[2];
1600 bytes[1] = rawBytes[3];
1601 bytes[0] = rawBytes[4];
1602 }
1603#else
1604 char *bytes =
1605 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT40;
1606 if (k_SIZEOF_INT40 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT40)) {
1607 validate();
1608 }
1609#endif
1610
1611 return *this;
1612}
1613
1614template <class STREAMBUF>
1615inline
1618{
1619 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1621 return *this; // RETURN
1622 }
1623
1624 invalidate();
1625
1626 if (sizeof variable > k_SIZEOF_INT32) {
1627 const int current = d_streamBuf->sgetc();
1629 STREAMBUF::traits_type::eof() == current)) {
1631 return *this; // RETURN
1632 }
1633 variable = 0x80 & current ? -1 : 0; // sign extend
1634 }
1635
1636#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1637 char *bytes = reinterpret_cast<char *>(&variable);
1638 char rawBytes[k_SIZEOF_INT32];
1639 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT32)) {
1640 validate();
1641 bytes[3] = rawBytes[0];
1642 bytes[2] = rawBytes[1];
1643 bytes[1] = rawBytes[2];
1644 bytes[0] = rawBytes[3];
1645 }
1646#else
1647 char *bytes =
1648 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT32;
1649 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT32)) {
1650 validate();
1651 }
1652#endif
1653
1654 return *this;
1655}
1656
1657template <class STREAMBUF>
1658inline
1661{
1662 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1664 return *this; // RETURN
1665 }
1666
1667 invalidate();
1668
1669 if (sizeof variable > k_SIZEOF_INT32) {
1670 variable = 0; // zero-extend
1671 }
1672
1673#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1674 char *bytes = reinterpret_cast<char *>(&variable);
1675 char rawBytes[k_SIZEOF_INT32];
1676 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT32)) {
1677 validate();
1678 bytes[3] = rawBytes[0];
1679 bytes[2] = rawBytes[1];
1680 bytes[1] = rawBytes[2];
1681 bytes[0] = rawBytes[3];
1682 }
1683#else
1684 char *bytes =
1685 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT32;
1686 if (k_SIZEOF_INT32 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT32)) {
1687 validate();
1688 }
1689#endif
1690
1691 return *this;
1692}
1693
1694template <class STREAMBUF>
1695inline
1698{
1699 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1701 return *this; // RETURN
1702 }
1703
1704 invalidate();
1705
1706 const int current = d_streamBuf->sgetc();
1708 STREAMBUF::traits_type::eof() == current)) {
1710 return *this; // RETURN
1711 }
1712 variable = 0x80 & current ? -1 : 0; // sign extend
1713
1714#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1715 char *bytes = reinterpret_cast<char *>(&variable);
1716 char rawBytes[k_SIZEOF_INT24];
1717 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT24)) {
1718 validate();
1719 bytes[2] = rawBytes[0];
1720 bytes[1] = rawBytes[1];
1721 bytes[0] = rawBytes[2];
1722 }
1723#else
1724 char *bytes =
1725 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT24;
1726 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT24)) {
1727 validate();
1728 }
1729#endif
1730
1731 return *this;
1732}
1733
1734template <class STREAMBUF>
1735inline
1738{
1739 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1741 return *this; // RETURN
1742 }
1743
1744 invalidate();
1745
1746 variable = 0; // zero-extend
1747
1748#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1749 char *bytes = reinterpret_cast<char *>(&variable);
1750 char rawBytes[k_SIZEOF_INT24];
1751 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT24)) {
1752 validate();
1753 bytes[2] = rawBytes[0];
1754 bytes[1] = rawBytes[1];
1755 bytes[0] = rawBytes[2];
1756 }
1757#else
1758 char *bytes =
1759 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT24;
1760 if (k_SIZEOF_INT24 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT24)) {
1761 validate();
1762 }
1763#endif
1764
1765 return *this;
1766}
1767
1768template <class STREAMBUF>
1769inline
1772{
1773 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1775 return *this; // RETURN
1776 }
1777
1778 invalidate();
1779
1780 if (sizeof variable > k_SIZEOF_INT16) {
1781 const int current = d_streamBuf->sgetc();
1783 STREAMBUF::traits_type::eof() == current)) {
1785 return *this; // RETURN
1786 }
1787 variable = 0x80 & current ? -1 : 0; // sign extend
1788 }
1789
1790#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1791 char *bytes = reinterpret_cast<char *>(&variable);
1792 char rawBytes[k_SIZEOF_INT16];
1793 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT16)) {
1794 validate();
1795 bytes[1] = rawBytes[0];
1796 bytes[0] = rawBytes[1];
1797 }
1798#else
1799 char *bytes =
1800 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT16;
1801 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT16)) {
1802 validate();
1803 }
1804#endif
1805
1806 return *this;
1807}
1808
1809template <class STREAMBUF>
1810inline
1813{
1814 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1816 return *this; // RETURN
1817 }
1818
1819 invalidate();
1820
1821 if (sizeof variable > k_SIZEOF_INT16) {
1822 variable = 0; // zero-extend
1823 }
1824
1825#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1826 char *bytes = reinterpret_cast<char *>(&variable);
1827 char rawBytes[k_SIZEOF_INT16];
1828 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_INT16)) {
1829 validate();
1830 bytes[1] = rawBytes[0];
1831 bytes[0] = rawBytes[1];
1832 }
1833#else
1834 char *bytes =
1835 reinterpret_cast<char *>(&variable) + sizeof variable - k_SIZEOF_INT16;
1836 if (k_SIZEOF_INT16 == d_streamBuf->sgetn(bytes, k_SIZEOF_INT16)) {
1837 validate();
1838 }
1839#endif
1840
1841 return *this;
1842}
1843
1844template <class STREAMBUF>
1845inline
1848{
1849 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1851 return *this; // RETURN
1852 }
1853
1854 invalidate();
1855
1856 const int current = d_streamBuf->sbumpc();
1857 if (STREAMBUF::traits_type::eof() != current) {
1858 validate();
1859 variable = static_cast<char>(current);
1860 }
1861
1862 return *this;
1863}
1864
1865template <class STREAMBUF>
1866inline
1869{
1870 return getInt8(reinterpret_cast<char&>(variable));
1871}
1872
1873template <class STREAMBUF>
1874inline
1877{
1878 return getInt8(variable);
1879}
1880
1881template <class STREAMBUF>
1882inline
1885{
1886 return getInt8(reinterpret_cast<char&>(variable));
1887}
1888
1889 // *** scalar floating-point values ***
1890
1891template <class STREAMBUF>
1892inline
1895{
1896 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1898 return *this; // RETURN
1899 }
1900
1901 invalidate();
1902
1903 if (sizeof variable > k_SIZEOF_FLOAT64) {
1904 variable = 0; // zero-fill mantissa
1905 }
1906
1907#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1908 char *bytes = reinterpret_cast<char *>(&variable);
1909 char rawBytes[k_SIZEOF_FLOAT64];
1910 if (k_SIZEOF_FLOAT64 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_FLOAT64)) {
1911 validate();
1912 bytes[sizeof variable - 1] = rawBytes[0];
1913 bytes[sizeof variable - 2] = rawBytes[1];
1914 bytes[sizeof variable - 3] = rawBytes[2];
1915 bytes[sizeof variable - 4] = rawBytes[3];
1916 bytes[sizeof variable - 5] = rawBytes[4];
1917 bytes[sizeof variable - 6] = rawBytes[5];
1918 bytes[sizeof variable - 7] = rawBytes[6];
1919 bytes[sizeof variable - 8] = rawBytes[7];
1920 }
1921#else
1922 char *bytes = reinterpret_cast<char *>(&variable);
1923 if (k_SIZEOF_FLOAT64 == d_streamBuf->sgetn(bytes, k_SIZEOF_FLOAT64)) {
1924 validate();
1925 }
1926#endif
1927
1928 return *this;
1929}
1930
1931template <class STREAMBUF>
1932inline
1935{
1936 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1938 return *this; // RETURN
1939 }
1940
1941 invalidate();
1942
1943 if (sizeof variable > k_SIZEOF_FLOAT32) {
1944 variable = 0; // zero-fill mantissa
1945 }
1946
1947#ifdef BSLS_PLATFORM_IS_LITTLE_ENDIAN
1948 char *bytes = reinterpret_cast<char *>(&variable);
1949 char rawBytes[k_SIZEOF_FLOAT32];
1950 if (k_SIZEOF_FLOAT32 == d_streamBuf->sgetn(rawBytes, k_SIZEOF_FLOAT32)) {
1951 validate();
1952 bytes[sizeof variable - 1] = rawBytes[0];
1953 bytes[sizeof variable - 2] = rawBytes[1];
1954 bytes[sizeof variable - 3] = rawBytes[2];
1955 bytes[sizeof variable - 4] = rawBytes[3];
1956 }
1957#else
1958 char *bytes = reinterpret_cast<char *>(&variable);
1959 if (k_SIZEOF_FLOAT32 == d_streamBuf->sgetn(bytes, k_SIZEOF_FLOAT32)) {
1960 validate();
1961 }
1962#endif
1963
1964 return *this;
1965}
1966
1967 // *** string values ***
1968
1969template <class STREAMBUF>
1972{
1973 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1975 return *this; // RETURN
1976 }
1977
1978 int length = 0;
1979 getLength(length);
1980
1981 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1983 return *this; // RETURN
1984 }
1985
1986 // 'length' could be corrupt or invalid, so we limit the initial 'resize'
1987 // to something that can accommodate the preponderance of strings that will
1988 // arise in practice. The remaining portion of a string longer than 16M is
1989 // read in via a second pass.
1990
1991 enum { k_INITIAL_ALLOCATION_SIZE = 16 * 1024 * 1024 };
1992
1993 const int initialLength = length < k_INITIAL_ALLOCATION_SIZE
1994 ? length
1995 : k_INITIAL_ALLOCATION_SIZE;
1996
1997 variable.resize(initialLength);
1998
1999 if (0 == length) {
2000 return *this; // RETURN
2001 }
2002
2003 getArrayUint8(&variable.front(), initialLength);
2004 if (isValid() && length > initialLength) {
2005 variable.resize(length);
2006 getArrayUint8(&variable[initialLength], length - initialLength);
2007 }
2008
2009 return *this;
2010}
2011
2012 // *** arrays of integer values ***
2013
2014template <class STREAMBUF>
2017 int numVariables)
2018{
2019 BSLS_ASSERT(variables || 0 == numVariables);
2020 BSLS_ASSERT(0 <= numVariables);
2021
2023 || 0 == numVariables)) {
2025 return *this; // RETURN
2026 }
2027
2028 const bsls::Types::Int64 *end = variables + numVariables;
2029 for (; variables != end; ++variables) {
2030 getInt64(*variables);
2031 }
2032
2033 return *this;
2034}
2035
2036template <class STREAMBUF>
2039 int numVariables)
2040{
2041 BSLS_ASSERT(variables || 0 == numVariables);
2042 BSLS_ASSERT(0 <= numVariables);
2043
2045 || 0 == numVariables)) {
2047 return *this; // RETURN
2048 }
2049
2050 const bsls::Types::Uint64 *end = variables + numVariables;
2051 for (; variables != end; ++variables) {
2052 getUint64(*variables);
2053 }
2054
2055 return *this;
2056}
2057
2058template <class STREAMBUF>
2061 int numVariables)
2062{
2063 BSLS_ASSERT(variables || 0 == numVariables);
2064 BSLS_ASSERT(0 <= numVariables);
2065
2067 || 0 == numVariables)) {
2069 return *this; // RETURN
2070 }
2071
2072 const bsls::Types::Int64 *end = variables + numVariables;
2073 for (; variables != end; ++variables) {
2074 getInt56(*variables);
2075 }
2076
2077 return *this;
2078}
2079
2080template <class STREAMBUF>
2083 int numVariables)
2084{
2085 BSLS_ASSERT(variables || 0 == numVariables);
2086 BSLS_ASSERT(0 <= numVariables);
2087
2089 || 0 == numVariables)) {
2091 return *this; // RETURN
2092 }
2093
2094 const bsls::Types::Uint64 *end = variables + numVariables;
2095 for (; variables != end; ++variables) {
2096 getUint56(*variables);
2097 }
2098
2099 return *this;
2100}
2101
2102template <class STREAMBUF>
2105 int numVariables)
2106{
2107 BSLS_ASSERT(variables || 0 == numVariables);
2108 BSLS_ASSERT(0 <= numVariables);
2109
2111 || 0 == numVariables)) {
2113 return *this; // RETURN
2114 }
2115
2116 const bsls::Types::Int64 *end = variables + numVariables;
2117 for (; variables != end; ++variables) {
2118 getInt48(*variables);
2119 }
2120
2121 return *this;
2122}
2123
2124template <class STREAMBUF>
2127 int numVariables)
2128{
2129 BSLS_ASSERT(variables || 0 == numVariables);
2130 BSLS_ASSERT(0 <= numVariables);
2131
2133 || 0 == numVariables)) {
2135 return *this; // RETURN
2136 }
2137
2138 const bsls::Types::Uint64 *end = variables + numVariables;
2139 for (; variables != end; ++variables) {
2140 getUint48(*variables);
2141 }
2142
2143 return *this;
2144}
2145
2146template <class STREAMBUF>
2149 int numVariables)
2150{
2151 BSLS_ASSERT(variables || 0 == numVariables);
2152 BSLS_ASSERT(0 <= numVariables);
2153
2155 || 0 == numVariables)) {
2157 return *this; // RETURN
2158 }
2159
2160 const bsls::Types::Int64 *end = variables + numVariables;
2161 for (; variables != end; ++variables) {
2162 getInt40(*variables);
2163 }
2164
2165 return *this;
2166}
2167
2168template <class STREAMBUF>
2171 int numVariables)
2172{
2173 BSLS_ASSERT(variables || 0 == numVariables);
2174 BSLS_ASSERT(0 <= numVariables);
2175
2177 || 0 == numVariables)) {
2179 return *this; // RETURN
2180 }
2181
2182 const bsls::Types::Uint64 *end = variables + numVariables;
2183 for (; variables != end; ++variables) {
2184 getUint40(*variables);
2185 }
2186
2187 return *this;
2188}
2189
2190template <class STREAMBUF>
2192GenericInStream<STREAMBUF>::getArrayInt32(int *variables, int numVariables)
2193{
2194 BSLS_ASSERT(variables || 0 == numVariables);
2195 BSLS_ASSERT(0 <= numVariables);
2196
2198 || 0 == numVariables)) {
2200 return *this; // RETURN
2201 }
2202
2203 const int *end = variables + numVariables;
2204 for (; variables != end; ++variables) {
2205 getInt32(*variables);
2206 }
2207
2208 return *this;
2209}
2210
2211template <class STREAMBUF>
2214 int numVariables)
2215{
2216 BSLS_ASSERT(variables || 0 == numVariables);
2217 BSLS_ASSERT(0 <= numVariables);
2218
2220 || 0 == numVariables)) {
2222 return *this; // RETURN
2223 }
2224
2225 const unsigned int *end = variables + numVariables;
2226 for (; variables != end; ++variables) {
2227 getUint32(*variables);
2228 }
2229
2230 return *this;
2231}
2232
2233template <class STREAMBUF>
2235GenericInStream<STREAMBUF>::getArrayInt24(int *variables, int numVariables)
2236{
2237 BSLS_ASSERT(variables || 0 == numVariables);
2238 BSLS_ASSERT(0 <= numVariables);
2239
2241 || 0 == numVariables)) {
2243 return *this; // RETURN
2244 }
2245
2246 const int *end = variables + numVariables;
2247 for (; variables != end; ++variables) {
2248 getInt24(*variables);
2249 }
2250
2251 return *this;
2252}
2253
2254template <class STREAMBUF>
2257 int numVariables)
2258{
2259 BSLS_ASSERT(variables || 0 == numVariables);
2260 BSLS_ASSERT(0 <= numVariables);
2261
2263 || 0 == numVariables)) {
2265 return *this; // RETURN
2266 }
2267
2268 const unsigned int *end = variables + numVariables;
2269 for (; variables != end; ++variables) {
2270 getUint24(*variables);
2271 }
2272
2273 return *this;
2274}
2275
2276template <class STREAMBUF>
2279 int numVariables)
2280{
2281 BSLS_ASSERT(variables || 0 == numVariables);
2282 BSLS_ASSERT(0 <= numVariables);
2283
2285 || 0 == numVariables)) {
2287 return *this; // RETURN
2288 }
2289
2290 const short *end = variables + numVariables;
2291 for (; variables != end; ++variables) {
2292 getInt16(*variables);
2293 }
2294
2295 return *this;
2296}
2297
2298template <class STREAMBUF>
2301 int numVariables)
2302{
2303 BSLS_ASSERT(variables || 0 == numVariables);
2304 BSLS_ASSERT(0 <= numVariables);
2305
2307 || 0 == numVariables)) {
2309 return *this; // RETURN
2310 }
2311
2312 const unsigned short *end = variables + numVariables;
2313 for (; variables != end; ++variables) {
2314 getUint16(*variables);
2315 }
2316
2317 return *this;
2318}
2319
2320template <class STREAMBUF>
2323 int numVariables)
2324{
2325 BSLS_ASSERT(variables || 0 == numVariables);
2326 BSLS_ASSERT(0 <= numVariables);
2327
2329 || 0 == numVariables)) {
2331 return *this; // RETURN
2332 }
2333
2334 const char *end = variables + numVariables;
2335 for (; variables != end; ++variables) {
2336 getInt8(*variables);
2337 }
2338
2339 return *this;
2340}
2341
2342template <class STREAMBUF>
2343inline
2346 int numVariables)
2347{
2348 BSLS_ASSERT_SAFE(variables || 0 == numVariables);
2349 BSLS_ASSERT_SAFE(0 <= numVariables);
2350
2351 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
2352}
2353
2354template <class STREAMBUF>
2355inline
2358 int numVariables)
2359{
2360 BSLS_ASSERT_SAFE(variables || 0 == numVariables);
2361 BSLS_ASSERT_SAFE(0 <= numVariables);
2362
2363 return getArrayInt8(variables, numVariables);
2364}
2365
2366template <class STREAMBUF>
2367inline
2370 int numVariables)
2371{
2372 BSLS_ASSERT_SAFE(variables || 0 == numVariables);
2373 BSLS_ASSERT_SAFE(0 <= numVariables);
2374
2375 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
2376}
2377
2378 // *** arrays of floating-point values ***
2379
2380template <class STREAMBUF>
2383 int numVariables)
2384{
2385 BSLS_ASSERT(variables || 0 == numVariables);
2386 BSLS_ASSERT(0 <= numVariables);
2387
2389 || 0 == numVariables)) {
2391 return *this; // RETURN
2392 }
2393
2394 const double *end = variables + numVariables;
2395 for (; variables != end; ++variables) {
2396 getFloat64(*variables);
2397 }
2398
2399 return *this;
2400}
2401
2402template <class STREAMBUF>
2405 int numVariables)
2406{
2407 BSLS_ASSERT(variables || 0 == numVariables);
2408 BSLS_ASSERT(0 <= numVariables);
2409
2411 || 0 == numVariables)) {
2413 return *this; // RETURN
2414 }
2415
2416 const float *end = variables + numVariables;
2417 for (; variables != end; ++variables) {
2418 getFloat32(*variables);
2419 }
2420
2421 return *this;
2422}
2423
2424// ACCESSORS
2425template <class STREAMBUF>
2426inline
2428{
2429 return isValid() ? this : 0;
2430}
2431
2432template <class STREAMBUF>
2433inline
2435{
2436 return d_validFlag;
2437}
2438
2439template <class STREAMBUF, class TYPE>
2440inline
2443{
2444 return InStreamFunctions::bdexStreamIn(stream, value);
2445}
2446
2447} // close package namespace
2448
2449
2450#endif
2451
2452// ----------------------------------------------------------------------------
2453// Copyright 2014 Bloomberg Finance L.P.
2454//
2455// Licensed under the Apache License, Version 2.0 (the "License");
2456// you may not use this file except in compliance with the License.
2457// You may obtain a copy of the License at
2458//
2459// http://www.apache.org/licenses/LICENSE-2.0
2460//
2461// Unless required by applicable law or agreed to in writing, software
2462// distributed under the License is distributed on an "AS IS" BASIS,
2463// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2464// See the License for the specific language governing permissions and
2465// limitations under the License.
2466// ----------------------------- END-OF-FILE ----------------------------------
2467
2468/** @} */
2469/** @} */
2470/** @} */
Definition bslstl_string.h:1252
CHAR_TYPE & front()
Definition bslstl_string.h:6115
void resize(size_type newLength, CHAR_TYPE character)
Definition bslstl_string.h:5977
Definition bslx_genericinstream.h:591
GenericInStream & getInt16(short &variable)
Definition bslx_genericinstream.h:1771
GenericInStream & getArrayUint32(unsigned int *variables, int numVariables)
Definition bslx_genericinstream.h:2213
GenericInStream & getArrayInt40(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:2148
GenericInStream & getInt8(char &variable)
Definition bslx_genericinstream.h:1847
GenericInStream & getArrayUint16(unsigned short *variables, int numVariables)
Definition bslx_genericinstream.h:2300
GenericInStream & getArrayInt56(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:2060
GenericInStream & getUint16(unsigned short &variable)
Definition bslx_genericinstream.h:1812
~GenericInStream()
Destroy this object.
Definition bslx_genericinstream.h:1222
GenericInStream & getArrayFloat32(float *variables, int numVariables)
Definition bslx_genericinstream.h:2404
GenericInStream & getUint32(unsigned int &variable)
Definition bslx_genericinstream.h:1660
GenericInStream & getArrayInt32(int *variables, int numVariables)
Definition bslx_genericinstream.h:2192
GenericInStream & getInt48(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1459
GenericInStream & getArrayUint24(unsigned int *variables, int numVariables)
Definition bslx_genericinstream.h:2256
void invalidate()
Definition bslx_genericinstream.h:1279
GenericInStream & getFloat64(double &variable)
Definition bslx_genericinstream.h:1894
bool isValid() const
Definition bslx_genericinstream.h:2434
GenericInStream & getArrayFloat64(double *variables, int numVariables)
Definition bslx_genericinstream.h:2382
GenericInStream & getUint64(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1336
GenericInStream & getInt32(int &variable)
Definition bslx_genericinstream.h:1617
GenericInStream & getArrayInt24(int *variables, int numVariables)
Definition bslx_genericinstream.h:2235
GenericInStream & getUint56(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1421
GenericInStream & getInt56(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1377
GenericInStream & getUint24(unsigned int &variable)
Definition bslx_genericinstream.h:1737
GenericInStream & getArrayInt48(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:2104
GenericInStream & getArrayUint48(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:2126
GenericInStream & getInt64(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1289
GenericInStream & getVersion(int &version)
Definition bslx_genericinstream.h:1263
GenericInStream & getUint8(char &variable)
Definition bslx_genericinstream.h:1876
GenericInStream & getArrayUint8(char *variables, int numVariables)
Definition bslx_genericinstream.h:2357
GenericInStream & getLength(int &length)
Definition bslx_genericinstream.h:1229
GenericInStream & getString(bsl::string &variable)
Definition bslx_genericinstream.h:1971
GenericInStream & getArrayInt16(short *variables, int numVariables)
Definition bslx_genericinstream.h:2278
GenericInStream & getFloat32(float &variable)
Definition bslx_genericinstream.h:1934
GenericInStream & getUint48(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1502
GenericInStream & getArrayInt64(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_genericinstream.h:2016
GenericInStream & getInt24(int &variable)
Definition bslx_genericinstream.h:1697
GenericInStream & getArrayUint40(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:2170
GenericInStream & getUint40(bsls::Types::Uint64 &variable)
Definition bslx_genericinstream.h:1581
GenericInStream & getArrayInt8(char *variables, int numVariables)
Definition bslx_genericinstream.h:2322
GenericInStream & getArrayUint56(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:2082
GenericInStream & getInt40(bsls::Types::Int64 &variable)
Definition bslx_genericinstream.h:1539
GenericInStream & getArrayUint64(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_genericinstream.h:2038
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#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:1263
Definition bslx_byteinstream.h:377
ByteInStream & operator>>(ByteInStream &stream, TYPE &value)
Definition bslx_byteinstream.h:2047
unsigned long long Uint64
Definition bsls_types.h:139
long long Int64
Definition bsls_types.h:134