BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslx_byteinstream.h
Go to the documentation of this file.
1/// @file bslx_byteinstream.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslx_byteinstream.h -*-C++-*-
8#ifndef INCLUDED_BSLX_BYTEINSTREAM
9#define INCLUDED_BSLX_BYTEINSTREAM
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslx_byteinstream bslx_byteinstream
15/// @brief Provide a stream class for unexternalization of fundamental types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslx
19/// @{
20/// @addtogroup bslx_byteinstream
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslx_byteinstream-purpose"> Purpose</a>
25/// * <a href="#bslx_byteinstream-classes"> Classes </a>
26/// * <a href="#bslx_byteinstream-description"> Description </a>
27/// * <a href="#bslx_byteinstream-usage"> Usage </a>
28/// * <a href="#bslx_byteinstream-example-1-basic-unexternalization"> Example 1: Basic Unexternalization </a>
29///
30/// # Purpose {#bslx_byteinstream-purpose}
31/// Provide a stream class for unexternalization of fundamental types.
32///
33/// # Classes {#bslx_byteinstream-classes}
34///
35/// - bslx::ByteInStream: byte-array-based input stream for fundamental types
36///
37/// @see bslx_byteoutstream
38///
39/// # Description {#bslx_byteinstream-description}
40/// This component implements a byte-array-based input stream
41/// class, `bslx::ByteInStream`, that provides platform-independent input
42/// methods ("unexternalization") on values, and arrays of values, of
43/// fundamental types, and on `bsl::string`.
44///
45/// The `bslx::ByteInStream` type reads from a user-supplied buffer directly,
46/// with no data copying or assumption of ownership. The user must therefore
47/// make sure that the lifetime and visibility of the buffer is sufficient to
48/// satisfy the needs of the input stream.
49///
50/// This component is intended to be used in conjunction with the
51/// @ref bslx_byteoutstream "externalization" component. Each input method of
52/// `bslx::ByteInStream` reads either a value or a homogeneous array of values
53/// of a fundamental type, in a format that was written by the corresponding
54/// `bslx::ByteOutStream` method. In general, the user of this component cannot
55/// rely on being able to read data that was written by any mechanism other than
56/// `bslx::ByteOutStream`.
57///
58/// The supported types and required content are listed in the `bslx`
59/// package-level documentation under "Supported Types".
60///
61/// Note that input streams can be *invalidated* explicitly and queried for
62/// *validity* and *emptiness*. Reading from an initially invalid stream has no
63/// effect. Attempting to read beyond the end of a stream will automatically
64/// invalidate the stream. Whenever an inconsistent value is detected, the
65/// stream should be invalidated explicitly.
66///
67/// ## Usage {#bslx_byteinstream-usage}
68///
69///
70/// This section illustrates intended use of this component.
71///
72/// ### Example 1: Basic Unexternalization {#bslx_byteinstream-example-1-basic-unexternalization}
73///
74///
75/// Suppose we wish to implement a (deliberately simple) `MyPerson` class as a
76/// value-semantic object that supports BDEX externalization and
77/// unexternalization. In addition to whatever data and methods that we choose
78/// to put into our design, we must supply three methods having specific names
79/// and signatures in order to comply with the BDEX protocol: a class method
80/// `maxSupportedBdexVersion`, an accessor (i.e., a `const` method)
81/// `bdexStreamOut`, and a manipulator (i.e., a non-`const` method)
82/// `bdexStreamIn`. This example shows how to implement those three methods.
83///
84/// In this example we will not worry overly about "good design" of the
85/// `MyPerson` component, and we will declare but not implement illustrative
86/// methods and free operators, except for the three required BDEX methods,
87/// which are implemented in full. In particular, we will not make explicit use
88/// of `bslma` allocators; a more complete design would do so:
89///
90/// First, we implement `MyPerson`:
91/// @code
92/// class MyPerson {
93/// bsl::string d_firstName;
94/// bsl::string d_lastName;
95/// int d_age;
96///
97/// friend bool operator==(const MyPerson&, const MyPerson&);
98///
99/// public:
100/// // CLASS METHODS
101///
102/// /// Return the maximum valid BDEX format version, as indicated by
103/// /// the specified `versionSelector`, to be passed to the
104/// /// `bdexStreamOut` method. Note that it is highly recommended that
105/// /// `versionSelector` be formatted as "YYYYMMDD", a date
106/// /// representation. Also note that `versionSelector` should be a
107/// /// *compile*-time-chosen value that selects a format version
108/// /// supported by both externalizer and unexternalizer. See the
109/// /// `bslx` package-level documentation for more information on BDEX
110/// /// streaming of value-semantic types and containers.
111/// static int maxSupportedBdexVersion(int versionSelector);
112///
113/// // CREATORS
114///
115/// /// Create a default person.
116/// MyPerson();
117///
118/// /// Create a person having the specified `firstName`, `lastName`,
119/// /// and `age`.
120/// MyPerson(const char *firstName, const char *lastName, int age);
121///
122/// /// Create a person having the value of the specified `original`
123/// /// person.
124/// MyPerson(const MyPerson& original);
125///
126/// /// Destroy this object.
127/// ~MyPerson();
128///
129/// // MANIPULATORS
130///
131/// /// Assign to this person the value of the specified `rhs` person,
132/// /// and return a reference to this person.
133/// MyPerson& operator=(const MyPerson& rhs);
134///
135/// /// Assign to this object the value read from the specified input
136/// /// `stream` using the specified `version` format, and return a
137/// /// reference to `stream`. If `stream` is initially invalid, this
138/// /// operation has no effect. If `version` is not supported, this
139/// /// object is unaltered and `stream` is invalidated, but otherwise
140/// /// unmodified. If `version` is supported but `stream` becomes
141/// /// invalid during this operation, this object has an undefined, but
142/// /// valid, state. Note that no version is read from `stream`. See
143/// /// the `bslx` package-level documentation for more information on
144/// /// BDEX streaming of value-semantic types and containers.
145/// template <class STREAM>
146/// STREAM& bdexStreamIn(STREAM& stream, int version);
147///
148/// //...
149///
150/// // ACCESSORS
151///
152/// /// Return the age of this person.
153/// int age() const;
154///
155/// /// Write the value of this object, using the specified `version`
156/// /// format, to the specified output `stream`, and return a reference
157/// /// to `stream`. If `stream` is initially invalid, this operation
158/// /// has no effect. If `version` is not supported, `stream` is
159/// /// invalidated, but otherwise unmodified. Note that `version` is
160/// /// not written to `stream`. See the `bslx` package-level
161/// /// documentation for more information on BDEX streaming of
162/// /// value-semantic types and containers.
163/// template <class STREAM>
164/// STREAM& bdexStreamOut(STREAM& stream, int version) const;
165///
166/// /// Return the first name of this person.
167/// const bsl::string& firstName() const;
168///
169/// /// Return the last name of this person.
170/// const bsl::string& lastName() const;
171///
172/// //...
173///
174/// };
175///
176/// // FREE OPERATORS
177///
178/// /// Return `true` if the specified `lhs` and `rhs` person objects have
179/// /// the same value, and `false` otherwise. Two person objects have the
180/// /// same value if they have the same first name, last name, and age.
181/// bool operator==(const MyPerson& lhs, const MyPerson& rhs);
182///
183/// /// Return 'true' if the specified 'lhs' and 'rhs' person objects do not
184/// /// have the same value, and 'false' otherwise. Two person objects
185/// /// differ in value if they differ in first name, last name, or age.
186/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs);
187///
188/// // ========================================================================
189/// // INLINE FUNCTION DEFINITIONS
190/// // ========================================================================
191///
192/// // CLASS METHODS
193/// inline
194/// int MyPerson::maxSupportedBdexVersion(int /* versionSelector */) {
195/// return 1;
196/// }
197///
198/// // CREATORS
199/// inline
200/// MyPerson::MyPerson()
201/// : d_firstName("")
202/// , d_lastName("")
203/// , d_age(0)
204/// {
205/// }
206///
207/// inline
208/// MyPerson::MyPerson(const char *firstName, const char *lastName, int age)
209/// : d_firstName(firstName)
210/// , d_lastName(lastName)
211/// , d_age(age)
212/// {
213/// }
214///
215/// inline
216/// MyPerson::~MyPerson()
217/// {
218/// }
219///
220/// template <class STREAM>
221/// STREAM& MyPerson::bdexStreamIn(STREAM& stream, int version)
222/// {
223/// if (stream) {
224/// switch (version) { // switch on the 'bslx' version
225/// case 1: {
226/// stream.getString(d_firstName);
227/// if (!stream) {
228/// d_firstName = "stream error"; // *might* be corrupted;
229/// // value for testing
230/// return stream; // RETURN
231/// }
232/// stream.getString(d_lastName);
233/// if (!stream) {
234/// d_lastName = "stream error"; // *might* be corrupted;
235/// // value for testing
236/// return stream; // RETURN
237/// }
238/// stream.getInt32(d_age);
239/// if (!stream) {
240/// d_age = 999; // *might* be corrupted; value for testing
241/// return stream; // RETURN
242/// }
243/// } break;
244/// default: {
245/// stream.invalidate();
246/// }
247/// }
248/// }
249/// return stream;
250/// }
251///
252/// // ACCESSORS
253/// inline
254/// int MyPerson::age() const
255/// {
256/// return d_age;
257/// }
258///
259/// template <class STREAM>
260/// STREAM& MyPerson::bdexStreamOut(STREAM& stream, int version) const
261/// {
262/// switch (version) {
263/// case 1: {
264/// stream.putString(d_firstName);
265/// stream.putString(d_lastName);
266/// stream.putInt32(d_age);
267/// } break;
268/// default: {
269/// stream.invalidate();
270/// } break;
271/// }
272/// return stream;
273/// }
274///
275/// inline
276/// const bsl::string& MyPerson::firstName() const
277/// {
278/// return d_firstName;
279/// }
280///
281/// inline
282/// const bsl::string& MyPerson::lastName() const
283/// {
284/// return d_lastName;
285/// }
286///
287/// // FREE OPERATORS
288/// inline
289/// bool operator==(const MyPerson& lhs, const MyPerson& rhs)
290/// {
291/// return lhs.d_firstName == rhs.d_firstName &&
292/// lhs.d_lastName == rhs.d_lastName &&
293/// lhs.d_age == rhs.d_age;
294/// }
295///
296/// inline
297/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs)
298/// {
299/// return !(lhs == rhs);
300/// }
301/// @endcode
302/// Then, we can exercise the new `MyPerson` value-semantic class by
303/// externalizing and reconstituting an object. First, create a `MyPerson`
304/// `janeSmith` and a `bslx::ByteOutStream` `outStream`:
305/// @code
306/// MyPerson janeSmith("Jane", "Smith", 42);
307/// bslx::ByteOutStream outStream(20131127);
308/// const int VERSION = 1;
309/// outStream.putVersion(VERSION);
310/// janeSmith.bdexStreamOut(outStream, VERSION);
311/// assert(outStream.isValid());
312/// @endcode
313/// Next, create a `MyPerson` `janeCopy` initialized to the default value, and
314/// assert that `janeCopy` is different from `janeSmith`:
315/// @code
316/// MyPerson janeCopy;
317/// assert(janeCopy != janeSmith);
318/// @endcode
319/// Then, create a `bslx::ByteInStream` `inStream` initialized with the buffer
320/// from the `bslx::ByteOutStream` object `outStream` and unexternalize this
321/// data into `janeCopy`:
322/// @code
323/// bslx::ByteInStream inStream(outStream.data(), outStream.length());
324/// int version;
325/// inStream.getVersion(version);
326/// janeCopy.bdexStreamIn(inStream, version);
327/// assert(inStream.isValid());
328/// @endcode
329/// Finally, `assert` the obtained values are as expected and display the
330/// results to `bsl::stdout`:
331/// @code
332/// assert(version == VERSION);
333/// assert(janeCopy == janeSmith);
334///
335/// if (janeCopy == janeSmith) {
336/// bsl::cout << "Successfully serialized and de-serialized Jane Smith:"
337/// << "\n\tFirstName: " << janeCopy.firstName()
338/// << "\n\tLastName : " << janeCopy.lastName()
339/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
340/// }
341/// else {
342/// bsl::cout << "Serialization unsuccessful. 'janeCopy' holds:"
343/// << "\n\tFirstName: " << janeCopy.firstName()
344/// << "\n\tLastName : " << janeCopy.lastName()
345/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
346/// }
347/// @endcode
348/// @}
349/** @} */
350/** @} */
351
352/** @addtogroup bsl
353 * @{
354 */
355/** @addtogroup bslx
356 * @{
357 */
358/** @addtogroup bslx_byteinstream
359 * @{
360 */
361
362#include <bslscm_version.h>
363
365#include <bslx_marshallingutil.h>
366
367#include <bsls_assert.h>
368#include <bsls_performancehint.h>
369#include <bsls_types.h>
370
371#include <bsl_cstddef.h>
372#include <bsl_iosfwd.h>
373#include <bsl_string.h>
374#include <bsl_vector.h>
375
376
377namespace bslx {
378
379 // ==================
380 // class ByteInStream
381 // ==================
382
383/// This class provides input methods to unexternalize values, and C-style
384/// arrays of values, of the fundamental integral and floating-point types,
385/// as well as `bsl::string` values, using a byte format documented in the
386/// @ref bslx_byteoutstream component. In particular, each `get` method of
387/// this class is guaranteed to read stream data written by the
388/// corresponding `put` method of `bslx::ByteOutStream`. Note that
389/// attempting to read beyond the end of a stream will automatically
390/// invalidate the stream. See the `bslx` package-level documentation for
391/// the definition of the BDEX `InStream` protocol.
392///
393/// See @ref bslx_byteinstream
395
396 // DATA
397 const char *d_buffer; // bytes to be unexternalized
398
399 bsl::size_t d_numBytes; // number of bytes in 'd_buffer'
400
401 bool d_validFlag; // stream validity flag; 'true' if stream is in
402 // valid state, 'false' otherwise
403
404 bsl::size_t d_cursor; // index of the next byte to be extracted from
405 // this stream
406
407 // FRIENDS
408 friend bsl::ostream& operator<<(bsl::ostream& stream,
409 const ByteInStream& object);
410
411 private:
412 // NOT IMPLEMENTED
414 ByteInStream& operator=(const ByteInStream&);
415
416 public:
417 // CREATORS
418
419 /// Create an empty input byte stream. Note that the constructed object
420 /// is useless until a buffer is set with the `reset` method.
421 explicit ByteInStream();
422
423 /// Create an input byte stream containing the specified initial
424 /// `numBytes` from the specified `buffer`. The behavior is undefined
425 /// unless `0 == numBytes` if `0 == buffer`.
426 ByteInStream(const char *buffer, bsl::size_t numBytes);
427
428 /// Create an input byte stream containing the specified `srcData`.
429 explicit ByteInStream(const bslstl::StringRef& srcData);
430
431 /// Destroy this object.
433
434 // MANIPULATORS
435
436 /// If the most-significant bit of the one byte of this stream at the
437 /// current cursor location is set, assign to the specified `length` the
438 /// four-byte, two's complement integer (in host byte order) comprised
439 /// of the four bytes of this stream at the current cursor location (in
440 /// network byte order) with the most-significant bit unset; otherwise,
441 /// assign to `length` the one-byte, two's complement integer comprised
442 /// of the one byte of this stream at the current cursor location.
443 /// Update the cursor location and return a reference to this stream.
444 /// If this stream is initially invalid, this operation has no effect.
445 /// If this function otherwise fails to extract a valid value, this
446 /// stream is marked invalid and the value of `length` is undefined.
447 /// Note that the value will be zero-extended.
449
450 /// Assign to the specified `version` the one-byte, two's complement
451 /// unsigned integer comprised of the one byte of this stream at the
452 /// current cursor location, update the cursor location, and return a
453 /// reference to this stream. If this stream is initially invalid, this
454 /// operation has no effect. If this function otherwise fails to
455 /// extract a valid value, this stream is marked invalid and the value
456 /// of `version` is undefined. Note that the value will be
457 /// zero-extended.
458 ByteInStream& getVersion(int& version);
459
460 /// Put this input stream in an invalid state. This function has no
461 /// effect if this stream is already invalid. Note that this function
462 /// should be called whenever a value extracted from this stream is
463 /// determined to be invalid, inconsistent, or otherwise incorrect.
464 void invalidate();
465
466 /// Set the index of the next byte to be extracted from this stream to 0
467 /// (i.e., the beginning of the stream) and validate this stream if it
468 /// is currently invalid.
469 void reset();
470
471 /// Reset this stream to extract from the specified `buffer` containing
472 /// the specified `numBytes`, set the index of the next byte to be
473 /// extracted to 0 (i.e., the beginning of the stream), and validate
474 /// this stream if it is currently invalid. The behavior is undefined
475 /// unless `0 == numBytes` if `0 == buffer`.
476 void reset(const char *buffer, bsl::size_t numBytes);
477
478 /// Reset this stream to extract from the specified `srcData`, set the
479 /// index of the next byte to be extracted to 0 (i.e., the beginning of
480 /// the stream), and validate this stream if it is currently invalid.
481 void reset(const bslstl::StringRef& srcData);
482
483 // *** scalar integer values ***
484
485 /// Assign to the specified `variable` the eight-byte, two's complement
486 /// integer (in host byte order) comprised of the eight bytes of this
487 /// stream at the current cursor location (in network byte order),
488 /// update the cursor location, and return a reference to this stream.
489 /// If this stream is initially invalid, this operation has no effect.
490 /// If this function otherwise fails to extract a valid value, this
491 /// stream is marked invalid and the value of `variable` is undefined.
492 /// Note that the value will be sign-extended.
494
495 /// Assign to the specified `variable` the eight-byte, two's complement
496 /// unsigned integer (in host byte order) comprised of the eight bytes
497 /// of this stream at the current cursor location (in network byte
498 /// order), update the cursor location, and return a reference to this
499 /// stream. If this stream is initially invalid, this operation has no
500 /// effect. If this function otherwise fails to extract a valid value,
501 /// this stream is marked invalid and the value of `variable` is
502 /// undefined. Note that the value will be zero-extended.
504
505 /// Assign to the specified `variable` the seven-byte, two's complement
506 /// integer (in host byte order) comprised of the seven bytes of this
507 /// stream at the current cursor location (in network byte order),
508 /// update the cursor location, and return a reference to this stream.
509 /// If this stream is initially invalid, this operation has no effect.
510 /// If this function otherwise fails to extract a valid value, this
511 /// stream is marked invalid and the value of `variable` is undefined.
512 /// Note that the value will be sign-extended.
514
515 /// Assign to the specified `variable` the seven-byte, two's complement
516 /// unsigned integer (in host byte order) comprised of the seven bytes
517 /// of this stream at the current cursor location (in network byte
518 /// order), update the cursor location, and return a reference to this
519 /// stream. If this stream is initially invalid, this operation has no
520 /// effect. If this function otherwise fails to extract a valid value,
521 /// this stream is marked invalid and the value of `variable` is
522 /// undefined. Note that the value will be zero-extended.
524
525 /// Assign to the specified `variable` the six-byte, two's complement
526 /// integer (in host byte order) comprised of the six bytes of this
527 /// stream at the current cursor location (in network byte order),
528 /// update the cursor location, and return a reference to this stream.
529 /// If this stream is initially invalid, this operation has no effect.
530 /// If this function otherwise fails to extract a valid value, this
531 /// stream is marked invalid and the value of `variable` is undefined.
532 /// Note that the value will be sign-extended.
534
535 /// Assign to the specified `variable` the six-byte, two's complement
536 /// unsigned integer (in host byte order) comprised of the six bytes of
537 /// this stream at the current cursor location (in network byte order),
538 /// update the cursor location, and return a reference to this stream.
539 /// If this stream is initially invalid, this operation has no effect.
540 /// If this function otherwise fails to extract a valid value, this
541 /// stream is marked invalid and the value of `variable` is undefined.
542 /// Note that the value will be zero-extended.
544
545 /// Assign to the specified `variable` the five-byte, two's complement
546 /// integer (in host byte order) comprised of the five bytes of this
547 /// stream at the current cursor location (in network byte order),
548 /// update the cursor location, and return a reference to this stream.
549 /// If this stream is initially invalid, this operation has no effect.
550 /// If this function otherwise fails to extract a valid value, this
551 /// stream is marked invalid and the value of `variable` is undefined.
552 /// Note that the value will be sign-extended.
554
555 /// Assign to the specified `variable` the five-byte, two's complement
556 /// unsigned integer (in host byte order) comprised of the five bytes of
557 /// this stream at the current cursor location (in network byte order),
558 /// update the cursor location, and return a reference to this stream.
559 /// If this stream is initially invalid, this operation has no effect.
560 /// If this function otherwise fails to extract a valid value, this
561 /// stream is marked invalid and the value of `variable` is undefined.
562 /// Note that the value will be zero-extended.
564
565 /// Assign to the specified `variable` the four-byte, two's complement
566 /// integer (in host byte order) comprised of the four bytes of this
567 /// stream at the current cursor location (in network byte order),
568 /// update the cursor location, and return a reference to this stream.
569 /// If this stream is initially invalid, this operation has no effect.
570 /// If this function otherwise fails to extract a valid value, this
571 /// stream is marked invalid and the value of `variable` is undefined.
572 /// Note that the value will be sign-extended.
573 ByteInStream& getInt32(int& variable);
574
575 /// Assign to the specified `variable` the four-byte, two's complement
576 /// unsigned integer (in host byte order) comprised of the four bytes of
577 /// this stream at the current cursor location (in network byte order),
578 /// update the cursor location, and return a reference to this stream.
579 /// If this stream is initially invalid, this operation has no effect.
580 /// If this function otherwise fails to extract a valid value, this
581 /// stream is marked invalid and the value of `variable` is undefined.
582 /// Note that the value will be zero-extended.
583 ByteInStream& getUint32(unsigned int& variable);
584
585 /// Assign to the specified `variable` the three-byte, two's complement
586 /// integer (in host byte order) comprised of the three bytes of this
587 /// stream at the current cursor location (in network byte order),
588 /// update the cursor location, and return a reference to this stream.
589 /// If this stream is initially invalid, this operation has no effect.
590 /// If this function otherwise fails to extract a valid value, this
591 /// stream is marked invalid and the value of `variable` is undefined.
592 /// Note that the value will be sign-extended.
593 ByteInStream& getInt24(int& variable);
594
595 /// Assign to the specified `variable` the three-byte, two's complement
596 /// unsigned integer (in host byte order) comprised of the three bytes
597 /// of this stream at the current cursor location (in network byte
598 /// order), update the cursor location, and return a reference to this
599 /// stream. If this stream is initially invalid, this operation has no
600 /// effect. If this function otherwise fails to extract a valid value,
601 /// this stream is marked invalid and the value of `variable` is
602 /// undefined. Note that the value will be zero-extended.
603 ByteInStream& getUint24(unsigned int& variable);
604
605 /// Assign to the specified `variable` the two-byte, two's complement
606 /// integer (in host byte order) comprised of the two bytes of this
607 /// stream at the current cursor location (in network byte order),
608 /// update the cursor location, and return a reference to this stream.
609 /// If this stream is initially invalid, this operation has no effect.
610 /// If this function otherwise fails to extract a valid value, this
611 /// stream is marked invalid and the value of `variable` is undefined.
612 /// Note that the value will be sign-extended.
613 ByteInStream& getInt16(short& variable);
614
615 /// Assign to the specified `variable` the two-byte, two's complement
616 /// unsigned integer (in host byte order) comprised of the two bytes of
617 /// this stream at the current cursor location (in network byte order),
618 /// update the cursor location, and return a reference to this stream.
619 /// If this stream is initially invalid, this operation has no effect.
620 /// If this function otherwise fails to extract a valid value, this
621 /// stream is marked invalid and the value of `variable` is undefined.
622 /// Note that the value will be zero-extended.
623 ByteInStream& getUint16(unsigned short& variable);
624
625 /// Assign to the specified `variable` the one-byte, two's complement
626 /// integer comprised of the one byte of this stream at the current
627 /// cursor location, update the cursor location, and return a reference
628 /// to this stream. If this stream is initially invalid, this operation
629 /// has no effect. If this function otherwise fails to extract a valid
630 /// value, this stream is marked invalid and the value of `variable` is
631 /// undefined. Note that the value will be sign-extended.
632 ByteInStream& getInt8(char& variable);
633 ByteInStream& getInt8(signed char& variable);
634
635 /// Assign to the specified `variable` the one-byte, two's complement
636 /// unsigned integer comprised of the one byte of this stream at the
637 /// current cursor location, update the cursor location, and return a
638 /// reference to this stream. If this stream is initially invalid, this
639 /// operation has no effect. If this function otherwise fails to
640 /// extract a valid value, this stream is marked invalid and the value
641 /// of `variable` is undefined. Note that the value will be
642 /// zero-extended.
643 ByteInStream& getUint8(char& variable);
644 ByteInStream& getUint8(unsigned char& variable);
645
646 // *** scalar floating-point values ***
647
648 /// Assign to the specified `variable` the eight-byte IEEE
649 /// double-precision floating-point number (in host byte order)
650 /// comprised of the eight bytes of this stream at the current cursor
651 /// location (in network byte order), update the cursor location, and
652 /// return a reference to this stream. If this stream is initially
653 /// invalid, this operation has no effect. If this function otherwise
654 /// fails to extract a valid value, this stream is marked invalid and
655 /// the value of `variable` is undefined.
656 ByteInStream& getFloat64(double& variable);
657
658 /// Assign to the specified `variable` the four-byte IEEE
659 /// single-precision floating-point number (in host byte order)
660 /// comprised of the four bytes of this stream at the current cursor
661 /// location (in network byte order), update the cursor location, and
662 /// return a reference to this stream. If this stream is initially
663 /// invalid, this operation has no effect. If this function otherwise
664 /// fails to extract a valid value, this stream is marked invalid and
665 /// the value of `variable` is undefined.
666 ByteInStream& getFloat32(float& variable);
667
668 // *** string values ***
669
670 /// Assign to the specified `variable` the string comprised of the
671 /// length of the string (see `getLength`) and the string data (see
672 /// `getUint8`), update the cursor location, and return a reference to
673 /// this stream. If this stream is initially invalid, this operation
674 /// has no effect. If this function otherwise fails to extract a valid
675 /// value, this stream is marked invalid and the value of `variable` is
676 /// undefined.
678
679 // *** arrays of integer values ***
680
681 /// Assign to the specified `variables` the consecutive eight-byte,
682 /// two's complement integers (in host byte order) comprised of each of
683 /// the specified `numVariables` eight-byte sequences of this stream at
684 /// the current cursor location (in network byte order), update the
685 /// cursor location, and return a reference to this stream. If this
686 /// stream is initially invalid, this operation has no effect. If this
687 /// function otherwise fails to extract a valid value, this stream is
688 /// marked invalid and the value of `variables` is undefined. The
689 /// behavior is undefined unless `0 <= numVariables` and `variables` has
690 /// sufficient capacity. Note that each of the values will be
691 /// sign-extended.
693 int numVariables);
694
695 /// Assign to the specified `variables` the consecutive eight-byte,
696 /// two's complement unsigned integers (in host byte order) comprised of
697 /// each of the specified `numVariables` eight-byte sequences of this
698 /// stream at the current cursor location (in network byte order),
699 /// update the cursor location, and return a reference to this stream.
700 /// If this stream is initially invalid, this operation has no effect.
701 /// If this function otherwise fails to extract a valid value, this
702 /// stream is marked invalid and the value of `variables` is undefined.
703 /// The behavior is undefined unless `0 <= numVariables` and `variables`
704 /// has sufficient capacity. Note that each of the values will be
705 /// zero-extended.
707 int numVariables);
708
709 /// Assign to the specified `variables` the consecutive seven-byte,
710 /// two's complement integers (in host byte order) comprised of each of
711 /// the specified `numVariables` seven-byte sequences of this stream at
712 /// the current cursor location (in network byte order), update the
713 /// cursor location, and return a reference to this stream. If this
714 /// stream is initially invalid, this operation has no effect. If this
715 /// function otherwise fails to extract a valid value, this stream is
716 /// marked invalid and the value of `variables` is undefined. The
717 /// behavior is undefined unless `0 <= numVariables` and `variables` has
718 /// sufficient capacity. Note that each of the values will be
719 /// sign-extended.
721 int numVariables);
722
723 /// Assign to the specified `variables` the consecutive seven-byte,
724 /// two's complement unsigned integers (in host byte order) comprised of
725 /// each of the specified `numVariables` seven-byte sequences of this
726 /// stream at the current cursor location (in network byte order),
727 /// update the cursor location, and return a reference to this stream.
728 /// If this stream is initially invalid, this operation has no effect.
729 /// If this function otherwise fails to extract a valid value, this
730 /// stream is marked invalid and the value of `variables` is undefined.
731 /// The behavior is undefined unless `0 <= numVariables` and `variables`
732 /// has sufficient capacity. Note that each of the values will be
733 /// zero-extended.
735 int numVariables);
736
737 /// Assign to the specified `variables` the consecutive six-byte, two's
738 /// complement integers (in host byte order) comprised of each of the
739 /// specified `numVariables` six-byte sequences of this stream at the
740 /// current cursor location (in network byte order), update the cursor
741 /// location, and return a reference to this stream. If this stream is
742 /// initially invalid, this operation has no effect. If this function
743 /// otherwise fails to extract a valid value, this stream is marked
744 /// invalid and the value of `variables` is undefined. The behavior is
745 /// undefined unless `0 <= numVariables` and `variables` has sufficient
746 /// capacity. Note that each of the values will be sign-extended.
748 int numVariables);
749
750 /// Assign to the specified `variables` the consecutive six-byte, two's
751 /// complement unsigned integers (in host byte order) comprised of each
752 /// of the specified `numVariables` six-byte sequences of this stream at
753 /// the current cursor location (in network byte order), update the
754 /// cursor location, and return a reference to this stream. If this
755 /// stream is initially invalid, this operation has no effect. If this
756 /// function otherwise fails to extract a valid value, this stream is
757 /// marked invalid and the value of `variables` is undefined. The
758 /// behavior is undefined unless `0 <= numVariables` and `variables` has
759 /// sufficient capacity. Note that each of the values will be
760 /// zero-extended.
762 int numVariables);
763
764 /// Assign to the specified `variables` the consecutive five-byte, two's
765 /// complement integers (in host byte order) comprised of each of the
766 /// specified `numVariables` five-byte sequences of this stream at the
767 /// current cursor location (in network byte order), update the cursor
768 /// location, and return a reference to this stream. If this stream is
769 /// initially invalid, this operation has no effect. If this function
770 /// otherwise fails to extract a valid value, this stream is marked
771 /// invalid and the value of `variables` is undefined. The behavior is
772 /// undefined unless `0 <= numVariables` and `variables` has sufficient
773 /// capacity. Note that each of the values will be sign-extended.
775 int numVariables);
776
777 /// Assign to the specified `variables` the consecutive five-byte, two's
778 /// complement unsigned integers (in host byte order) comprised of each
779 /// of the specified `numVariables` five-byte sequences of this stream
780 /// at the current cursor location (in network byte order), update the
781 /// cursor location, and return a reference to this stream. If this
782 /// stream is initially invalid, this operation has no effect. If this
783 /// function otherwise fails to extract a valid value, this stream is
784 /// marked invalid and the value of `variables` is undefined. The
785 /// behavior is undefined unless `0 <= numVariables` and `variables` has
786 /// sufficient capacity. Note that each of the values will be
787 /// zero-extended.
789 int numVariables);
790
791 /// Assign to the specified `variables` the consecutive four-byte, two's
792 /// complement integers (in host byte order) comprised of each of the
793 /// specified `numVariables` four-byte sequences of this stream at the
794 /// current cursor location (in network byte order), update the cursor
795 /// location, and return a reference to this stream. If this stream is
796 /// initially invalid, this operation has no effect. If this function
797 /// otherwise fails to extract a valid value, this stream is marked
798 /// invalid and the value of `variables` is undefined. The behavior is
799 /// undefined unless `0 <= numVariables` and `variables` has sufficient
800 /// capacity. Note that each of the values will be sign-extended.
801 ByteInStream& getArrayInt32(int *variables, int numVariables);
802
803 /// Assign to the specified `variables` the consecutive four-byte, two's
804 /// complement unsigned integers (in host byte order) comprised of each
805 /// of the specified `numVariables` four-byte sequences of this stream
806 /// at the current cursor location (in network byte order), update the
807 /// cursor location, and return a reference to this stream. If this
808 /// stream is initially invalid, this operation has no effect. If this
809 /// function otherwise fails to extract a valid value, this stream is
810 /// marked invalid and the value of `variables` is undefined. The
811 /// behavior is undefined unless `0 <= numVariables` and `variables` has
812 /// sufficient capacity. Note that each of the values will be
813 /// zero-extended.
814 ByteInStream& getArrayUint32(unsigned int *variables, int numVariables);
815
816 /// Assign to the specified `variables` the consecutive three-byte,
817 /// two's complement integers (in host byte order) comprised of each of
818 /// the specified `numVariables` three-byte sequences of this stream at
819 /// the current cursor location (in network byte order), update the
820 /// cursor location, and return a reference to this stream. If this
821 /// stream is initially invalid, this operation has no effect. If this
822 /// function otherwise fails to extract a valid value, this stream is
823 /// marked invalid and the value of `variables` is undefined. The
824 /// behavior is undefined unless `0 <= numValues` and `variables` has
825 /// sufficient capacity. Note that each of the values will be
826 /// sign-extended.
827 ByteInStream& getArrayInt24(int *variables, int numVariables);
828
829 /// Assign to the specified `variables` the consecutive three-byte,
830 /// two's complement unsigned integers (in host byte order) comprised of
831 /// each of the specified `numVariables` three-byte sequences of this
832 /// stream at the current cursor location (in network byte order),
833 /// update the cursor location, and return a reference to this stream.
834 /// If this stream is initially invalid, this operation has no effect.
835 /// If this function otherwise fails to extract a valid value, this
836 /// stream is marked invalid and the value of `variables` is undefined.
837 /// The behavior is undefined unless `0 <= numVariables` and `variables`
838 /// has sufficient capacity. Note that each of the values will be
839 /// zero-extended.
840 ByteInStream& getArrayUint24(unsigned int *variables, int numVariables);
841
842 /// Assign to the specified `variables` the consecutive two-byte, two's
843 /// complement integers (in host byte order) comprised of each of the
844 /// specified `numVariables` two-byte sequences of this stream at the
845 /// current cursor location (in network byte order), update the cursor
846 /// location, and return a reference to this stream. If this stream is
847 /// initially invalid, this operation has no effect. If this function
848 /// otherwise fails to extract a valid value, this stream is marked
849 /// invalid and the value of `variables` is undefined. The behavior is
850 /// undefined unless `0 <= numVariables` and `variables` has sufficient
851 /// capacity. Note that each of the values will be sign-extended.
852 ByteInStream& getArrayInt16(short *variables, int numVariables);
853
854 /// Assign to the specified `variables` the consecutive two-byte, two's
855 /// complement unsigned integers (in host byte order) comprised of each
856 /// of the specified `numVariables` two-byte sequences of this stream at
857 /// the current cursor location (in network byte order), update the
858 /// cursor location, and return a reference to this stream. If this
859 /// stream is initially invalid, this operation has no effect. If this
860 /// function otherwise fails to extract a valid value, this stream is
861 /// marked invalid and the value of `variables` is undefined. The
862 /// behavior is undefined unless `0 <= numVariables` and `variables` has
863 /// sufficient capacity. Note that each of the values will be
864 /// zero-extended.
865 ByteInStream& getArrayUint16(unsigned short *variables, int numVariables);
866
867 /// Assign to the specified `variables` the consecutive one-byte, two's
868 /// complement integers comprised of each of the specified
869 /// `numVariables` one-byte sequences of this stream at the current
870 /// cursor location, update the cursor location, and return a reference
871 /// to this stream. If this stream is initially invalid, this operation
872 /// has no effect. If this function otherwise fails to extract a valid
873 /// value, this stream is marked invalid and the value of `variables` is
874 /// undefined. The behavior is undefined unless `0 <= numVariables` and
875 /// `variables` has sufficient capacity. Note that each of the values
876 /// will be sign-extended.
877 ByteInStream& getArrayInt8(char *variables, int numVariables);
878 ByteInStream& getArrayInt8(signed char *variables, int numVariables);
879
880 /// Assign to the specified `variables` the consecutive one-byte, two's
881 /// complement unsigned integers comprised of each of the specified
882 /// `numVariables` one-byte sequences of this stream at the current
883 /// cursor location, update the cursor location, and return a reference
884 /// to this stream. If this stream is initially invalid, this operation
885 /// has no effect. If this function otherwise fails to extract a valid
886 /// value, this stream is marked invalid and the value of `variables` is
887 /// undefined. The behavior is undefined unless `0 <= numVariables` and
888 /// `variables` has sufficient capacity. Note that each of the values
889 /// will be zero-extended.
890 ByteInStream& getArrayUint8(char *variables, int numVariables);
891 ByteInStream& getArrayUint8(unsigned char *variables, int numVariables);
892
893 // *** arrays of floating-point values ***
894
895 /// Assign to the specified `variables` the consecutive eight-byte IEEE
896 /// double-precision floating-point numbers (in host byte order)
897 /// comprised of each of the specified `numVariables` eight-byte
898 /// sequences of this stream at the current cursor location (in network
899 /// byte order), update the cursor location, and return a reference to
900 /// this stream. If this stream is initially invalid, this operation
901 /// has no effect. If this function otherwise fails to extract a valid
902 /// value, this stream is marked invalid and the value of `variables` is
903 /// undefined. The behavior is undefined unless `0 <= numVariables` and
904 /// `variables` has sufficient capacity.
905 ByteInStream& getArrayFloat64(double *variables, int numVariables);
906
907 /// Assign to the specified `variables` the consecutive four-byte IEEE
908 /// single-precision floating-point numbers (in host byte order)
909 /// comprised of each of the specified `numVariables` four-byte
910 /// sequences of this stream at the current cursor location (in network
911 /// byte order), update the cursor location, and return a reference to
912 /// this stream. If this stream is initially invalid, this operation
913 /// has no effect. If this function otherwise fails to extract a valid
914 /// value, this stream is marked invalid and the value of `variables` is
915 /// undefined. The behavior is undefined unless `0 <= numVariables` and
916 /// `variables` has sufficient capacity.
917 ByteInStream& getArrayFloat32(float *variables, int numVariables);
918
919 // ACCESSORS
920
921 /// Return a non-zero value if this stream is valid, and 0 otherwise.
922 /// An invalid stream is a stream for which an input operation was
923 /// detected to have failed.
924 operator const void *() const;
925
926 /// Return the index of the next byte to be extracted from this stream.
927 bsl::size_t cursor() const;
928
929 /// Return the address of the contiguous, non-modifiable external memory
930 /// buffer of this stream. The behavior of accessing elements outside
931 /// the range `[ data() .. data() + (length() - 1) ]` is undefined.
932 const char *data() const;
933
934 /// Return `true` if this stream is empty, and `false` otherwise. Note
935 /// that this function enables higher-level types to verify that, after
936 /// successfully reading all expected data, no data remains.
937 bool isEmpty() const;
938
939 /// Return `true` if this stream is valid, and `false` otherwise. An
940 /// invalid stream is a stream in which insufficient or invalid data was
941 /// detected during an extraction operation. Note that an empty stream
942 /// will be valid unless an extraction attempt or explicit invalidation
943 /// causes it to be otherwise.
944 bool isValid() const;
945
946 /// Return the total number of bytes stored in the external memory
947 /// buffer.
948 bsl::size_t length() const;
949};
950
951// FREE OPERATORS
952
953/// Write the specified `object` to the specified output `stream` in some
954/// reasonable (multi-line) format, and return a reference to `stream`.
955bsl::ostream& operator<<(bsl::ostream& stream,
956 const ByteInStream& object);
957
958/// Read the specified `value` from the specified input `stream` following
959/// the requirements of the BDEX protocol (see the `bslx` package-level
960/// documentation), and return a reference to `stream`. The behavior is
961/// undefined unless `TYPE` is BDEX-compliant.
962template <class TYPE>
963ByteInStream& operator>>(ByteInStream& stream, TYPE& value);
964
965// ============================================================================
966// INLINE DEFINITIONS
967// ============================================================================
968
969 // ------------------
970 // class ByteInStream
971 // ------------------
972
973// CREATORS
974inline
976: d_buffer(0)
977, d_numBytes(0)
978, d_validFlag(true)
979, d_cursor(0)
980{
981}
982
983inline
984ByteInStream::ByteInStream(const char *buffer, bsl::size_t numBytes)
985: d_buffer(buffer)
986, d_numBytes(numBytes)
987, d_validFlag(true)
988, d_cursor(0)
989{
990 BSLS_ASSERT_SAFE(buffer || 0 == numBytes);
991}
992
993inline
995: d_buffer(srcData.data())
996, d_numBytes(static_cast<int>(srcData.length()))
997, d_validFlag(true)
998, d_cursor(0)
999{
1000}
1001
1002inline
1006
1007// MANIPULATORS
1008inline
1010{
1013 return *this; // RETURN
1014 }
1015
1017 if (127 < static_cast<unsigned char>(d_buffer[cursor()])) {
1018 // If 'length > 127', 'length' is stored as 4 bytes with top bit
1019 // set.
1020
1022 length &= 0x7fffffff; // Clear top bit.
1023 }
1024 else {
1025 // If 'length <= 127', 'length' is stored as one byte.
1026
1027 char tmp;
1030 length = tmp;
1031 }
1032 }
1033 else {
1034 invalidate();
1035 }
1036
1037 return *this;
1038}
1039
1040inline
1042{
1045 return *this; // RETURN
1046 }
1047
1048 unsigned char tmp = 0;
1049 getUint8(tmp);
1050 version = tmp;
1051
1052 return *this;
1053}
1054
1055inline
1057{
1058 d_validFlag = false;
1059}
1060
1061inline
1063{
1064 d_validFlag = true;
1065 d_cursor = 0;
1066}
1067
1068inline
1069void ByteInStream::reset(const char *buffer, bsl::size_t numBytes)
1070{
1071 BSLS_ASSERT_SAFE(buffer || 0 == numBytes);
1072
1073 d_buffer = buffer;
1074 d_numBytes = numBytes;
1075 d_validFlag = true;
1076 d_cursor = 0;
1077}
1078
1079inline
1081{
1082 d_buffer = srcData.data();
1083 d_numBytes = srcData.length();
1084 d_validFlag = true;
1085 d_cursor = 0;
1086}
1087
1088 // *** scalar integer values ***
1089
1090inline
1092{
1095 return *this; // RETURN
1096 }
1097
1099 MarshallingUtil::getInt64(&variable, d_buffer + cursor());
1101 }
1102 else {
1103 invalidate();
1104 }
1105
1106 return *this;
1107}
1108
1109inline
1111{
1114 return *this; // RETURN
1115 }
1116
1118 MarshallingUtil::getUint64(&variable, d_buffer + cursor());
1120 }
1121 else {
1122 invalidate();
1123 }
1124
1125 return *this;
1126}
1127
1128inline
1130{
1133 return *this; // RETURN
1134 }
1135
1137 MarshallingUtil::getInt56(&variable, d_buffer + cursor());
1139 }
1140 else {
1141 invalidate();
1142 }
1143
1144 return *this;
1145}
1146
1147inline
1149{
1152 return *this; // RETURN
1153 }
1154
1156 MarshallingUtil::getUint56(&variable, d_buffer + cursor());
1158 }
1159 else {
1160 invalidate();
1161 }
1162
1163 return *this;
1164}
1165
1166inline
1168{
1171 return *this; // RETURN
1172 }
1173
1175 MarshallingUtil::getInt48(&variable, d_buffer + cursor());
1177 }
1178 else {
1179 invalidate();
1180 }
1181
1182 return *this;
1183}
1184
1185inline
1187{
1190 return *this; // RETURN
1191 }
1192
1194 MarshallingUtil::getUint48(&variable, d_buffer + cursor());
1196 }
1197 else {
1198 invalidate();
1199 }
1200
1201 return *this;
1202}
1203
1204inline
1206{
1209 return *this; // RETURN
1210 }
1211
1213 MarshallingUtil::getInt40(&variable, d_buffer + cursor());
1215 }
1216 else {
1217 invalidate();
1218 }
1219
1220 return *this;
1221}
1222
1223inline
1225{
1228 return *this; // RETURN
1229 }
1230
1232 MarshallingUtil::getUint40(&variable, d_buffer + cursor());
1234 }
1235 else {
1236 invalidate();
1237 }
1238
1239 return *this;
1240}
1241
1242inline
1244{
1247 return *this; // RETURN
1248 }
1249
1251 MarshallingUtil::getInt32(&variable, d_buffer + cursor());
1253 }
1254 else {
1255 invalidate();
1256 }
1257
1258 return *this;
1259}
1260
1261inline
1263{
1266 return *this; // RETURN
1267 }
1268
1270 MarshallingUtil::getUint32(&variable, d_buffer + cursor());
1272 }
1273 else {
1274 invalidate();
1275 }
1276
1277 return *this;
1278}
1279
1280inline
1282{
1285 return *this; // RETURN
1286 }
1287
1289 MarshallingUtil::getInt24(&variable, d_buffer + cursor());
1291 }
1292 else {
1293 invalidate();
1294 }
1295
1296 return *this;
1297}
1298
1299inline
1301{
1304 return *this; // RETURN
1305 }
1306
1308 MarshallingUtil::getUint24(&variable, d_buffer + cursor());
1310 }
1311 else {
1312 invalidate();
1313 }
1314
1315 return *this;
1316}
1317
1318inline
1320{
1323 return *this; // RETURN
1324 }
1325
1327 MarshallingUtil::getInt16(&variable, d_buffer + cursor());
1329 }
1330 else {
1331 invalidate();
1332 }
1333
1334 return *this;
1335}
1336
1337inline
1338ByteInStream& ByteInStream::getUint16(unsigned short& variable)
1339{
1342 return *this; // RETURN
1343 }
1344
1346 MarshallingUtil::getUint16(&variable, d_buffer + cursor());
1348 }
1349 else {
1350 invalidate();
1351 }
1352
1353 return *this;
1354}
1355
1356inline
1358{
1361 return *this; // RETURN
1362 }
1363
1365 MarshallingUtil::getInt8(&variable, data() + cursor());
1367 }
1368 else {
1369 invalidate();
1370 }
1371
1372 return *this;
1373}
1374
1375inline
1377{
1378 return getInt8(reinterpret_cast<char&>(variable));
1379}
1380
1381inline
1383{
1384 return getInt8(variable);
1385}
1386
1387inline
1388ByteInStream& ByteInStream::getUint8(unsigned char& variable)
1389{
1390 return getInt8(reinterpret_cast<char&>(variable));
1391}
1392
1393 // *** scalar floating-point values ***
1394
1395inline
1397{
1400 return *this; // RETURN
1401 }
1402
1404 MarshallingUtil::getFloat64(&variable, d_buffer + cursor());
1406 }
1407 else {
1408 invalidate();
1409 }
1410
1411 return *this;
1412}
1413
1414inline
1416{
1419 return *this; // RETURN
1420 }
1421
1423 MarshallingUtil::getFloat32(&variable, d_buffer + cursor());
1425 }
1426 else {
1427 invalidate();
1428 }
1429
1430 return *this;
1431}
1432
1433 // *** string values ***
1434
1435inline
1437{
1440 return *this; // RETURN
1441 }
1442
1443 int length;
1445
1448 return *this; // RETURN
1449 }
1450
1451 // 'length' could be corrupt or invalid, so we limit the initial 'resize'
1452 // to something that can accommodate the preponderance of strings that will
1453 // arise in practice. The remaining portion of a string longer than 16M is
1454 // read in via a second pass.
1455
1456 enum { k_INITIAL_ALLOCATION_SIZE = 16 * 1024 * 1024 };
1457
1458 const int initialLength = length < k_INITIAL_ALLOCATION_SIZE
1459 ? length
1460 : k_INITIAL_ALLOCATION_SIZE;
1461
1462 variable.resize(initialLength);
1463
1464 if (0 == length) {
1465 return *this; // RETURN
1466 }
1467
1468 getArrayUint8(&variable.front(), initialLength);
1469 if (isValid() && length > initialLength) {
1470 variable.resize(length);
1471 getArrayUint8(&variable[initialLength], length - initialLength);
1472 }
1473
1474 return *this;
1475}
1476
1477 // *** arrays of integer values ***
1478
1479inline
1481 int numVariables)
1482{
1483 BSLS_ASSERT_SAFE(variables);
1484 BSLS_ASSERT_SAFE(0 <= numVariables);
1485
1488 return *this; // RETURN
1489 }
1490
1491 const int len = MarshallingUtil::k_SIZEOF_INT64 * numVariables;
1492 if (cursor() + len <= length()) {
1494 d_buffer + cursor(),
1495 numVariables);
1496 d_cursor += len;
1497 }
1498 else {
1499 invalidate();
1500 }
1501
1502 return *this;
1503}
1504
1505inline
1507 int numVariables)
1508{
1509 BSLS_ASSERT_SAFE(variables);
1510 BSLS_ASSERT_SAFE(0 <= numVariables);
1511
1514 return *this; // RETURN
1515 }
1516
1517 const int len = MarshallingUtil::k_SIZEOF_INT64 * numVariables;
1518 if (cursor() + len <= length()) {
1520 d_buffer + cursor(),
1521 numVariables);
1522 d_cursor += len;
1523 }
1524 else {
1525 invalidate();
1526 }
1527
1528 return *this;
1529}
1530
1531inline
1533 int numVariables)
1534{
1535 BSLS_ASSERT_SAFE(variables);
1536 BSLS_ASSERT_SAFE(0 <= numVariables);
1537
1540 return *this; // RETURN
1541 }
1542
1543 const int len = MarshallingUtil::k_SIZEOF_INT56 * numVariables;
1544 if (cursor() + len <= length()) {
1546 d_buffer + cursor(),
1547 numVariables);
1548 d_cursor += len;
1549 }
1550 else {
1551 invalidate();
1552 }
1553
1554 return *this;
1555}
1556
1557inline
1559 int numVariables)
1560{
1561 BSLS_ASSERT_SAFE(variables);
1562 BSLS_ASSERT_SAFE(0 <= numVariables);
1563
1566 return *this; // RETURN
1567 }
1568
1569 const int len = MarshallingUtil::k_SIZEOF_INT56 * numVariables;
1570 if (cursor() + len <= length()) {
1572 d_buffer + cursor(),
1573 numVariables);
1574 d_cursor += len;
1575 }
1576 else {
1577 invalidate();
1578 }
1579
1580 return *this;
1581}
1582
1583inline
1585 int numVariables)
1586{
1587 BSLS_ASSERT_SAFE(variables);
1588 BSLS_ASSERT_SAFE(0 <= numVariables);
1589
1592 return *this; // RETURN
1593 }
1594
1595 const int len = MarshallingUtil::k_SIZEOF_INT48 * numVariables;
1596 if (cursor() + len <= length()) {
1598 d_buffer + cursor(),
1599 numVariables);
1600 d_cursor += len;
1601 }
1602 else {
1603 invalidate();
1604 }
1605
1606 return *this;
1607}
1608
1609inline
1611 int numVariables)
1612{
1613 BSLS_ASSERT_SAFE(variables);
1614 BSLS_ASSERT_SAFE(0 <= numVariables);
1615
1618 return *this; // RETURN
1619 }
1620
1621 const int len = MarshallingUtil::k_SIZEOF_INT48 * numVariables;
1622 if (cursor() + len <= length()) {
1624 d_buffer + cursor(),
1625 numVariables);
1626 d_cursor += len;
1627 }
1628 else {
1629 invalidate();
1630 }
1631
1632 return *this;
1633}
1634
1635inline
1637 int numVariables)
1638{
1639 BSLS_ASSERT_SAFE(variables);
1640 BSLS_ASSERT_SAFE(0 <= numVariables);
1641
1644 return *this; // RETURN
1645 }
1646
1647 const int len = MarshallingUtil::k_SIZEOF_INT40 * numVariables;
1648 if (cursor() + len <= length()) {
1650 d_buffer + cursor(),
1651 numVariables);
1652 d_cursor += len;
1653 }
1654 else {
1655 invalidate();
1656 }
1657
1658 return *this;
1659}
1660
1661inline
1663 int numVariables)
1664{
1665 BSLS_ASSERT_SAFE(variables);
1666 BSLS_ASSERT_SAFE(0 <= numVariables);
1667
1670 return *this; // RETURN
1671 }
1672
1673 const int len = MarshallingUtil::k_SIZEOF_INT40 * numVariables;
1674 if (cursor() + len <= length()) {
1676 d_buffer + cursor(),
1677 numVariables);
1678 d_cursor += len;
1679 }
1680 else {
1681 invalidate();
1682 }
1683
1684 return *this;
1685}
1686
1687inline
1688ByteInStream& ByteInStream::getArrayInt32(int *variables, int numVariables)
1689{
1690 BSLS_ASSERT_SAFE(variables);
1691 BSLS_ASSERT_SAFE(0 <= numVariables);
1692
1695 return *this; // RETURN
1696 }
1697
1698 const int len = MarshallingUtil::k_SIZEOF_INT32 * numVariables;
1699 if (cursor() + len <= length()) {
1701 d_buffer + cursor(),
1702 numVariables);
1703 d_cursor += len;
1704 }
1705 else {
1706 invalidate();
1707 }
1708
1709 return *this;
1710}
1711
1712inline
1714 int numVariables)
1715{
1716 BSLS_ASSERT_SAFE(variables);
1717 BSLS_ASSERT_SAFE(0 <= numVariables);
1718
1721 return *this; // RETURN
1722 }
1723
1724 const int len = MarshallingUtil::k_SIZEOF_INT32 * numVariables;
1725 if (cursor() + len <= length()) {
1727 d_buffer + cursor(),
1728 numVariables);
1729 d_cursor += len;
1730 }
1731 else {
1732 invalidate();
1733 }
1734
1735 return *this;
1736}
1737
1738inline
1739ByteInStream& ByteInStream::getArrayInt24(int *variables, int numVariables)
1740{
1741 BSLS_ASSERT_SAFE(variables);
1742 BSLS_ASSERT_SAFE(0 <= numVariables);
1743
1746 return *this; // RETURN
1747 }
1748
1749 const int len = MarshallingUtil::k_SIZEOF_INT24 * numVariables;
1750 if (cursor() + len <= length()) {
1752 d_buffer + cursor(),
1753 numVariables);
1754 d_cursor += len;
1755 }
1756 else {
1757 invalidate();
1758 }
1759
1760 return *this;
1761}
1762
1763inline
1765 int numVariables)
1766{
1767 BSLS_ASSERT_SAFE(variables);
1768 BSLS_ASSERT_SAFE(0 <= numVariables);
1769
1772 return *this; // RETURN
1773 }
1774
1775 const int len = MarshallingUtil::k_SIZEOF_INT24 * numVariables;
1776 if (cursor() + len <= length()) {
1778 d_buffer + cursor(),
1779 numVariables);
1780 d_cursor += len;
1781 }
1782 else {
1783 invalidate();
1784 }
1785
1786 return *this;
1787}
1788
1789inline
1790ByteInStream& ByteInStream::getArrayInt16(short *variables, int numVariables)
1791{
1792 BSLS_ASSERT_SAFE(variables);
1793 BSLS_ASSERT_SAFE(0 <= numVariables);
1794
1797 return *this; // RETURN
1798 }
1799
1800 const int len = MarshallingUtil::k_SIZEOF_INT16 * numVariables;
1801 if (cursor() + len <= length()) {
1803 d_buffer + cursor(),
1804 numVariables);
1805 d_cursor += len;
1806 }
1807 else {
1808 invalidate();
1809 }
1810
1811 return *this;
1812}
1813
1814inline
1816 int numVariables)
1817{
1818 BSLS_ASSERT_SAFE(variables);
1819 BSLS_ASSERT_SAFE(0 <= numVariables);
1820
1823 return *this; // RETURN
1824 }
1825
1826 const int len = MarshallingUtil::k_SIZEOF_INT16 * numVariables;
1827 if (cursor() + len <= length()) {
1829 d_buffer + cursor(),
1830 numVariables);
1831 d_cursor += len;
1832 }
1833 else {
1834 invalidate();
1835 }
1836
1837 return *this;
1838}
1839
1840inline
1841ByteInStream& ByteInStream::getArrayInt8(char *variables, int numVariables)
1842{
1843 BSLS_ASSERT_SAFE(variables);
1844 BSLS_ASSERT_SAFE(0 <= numVariables);
1845
1848 return *this; // RETURN
1849 }
1850
1851 const int len = MarshallingUtil::k_SIZEOF_INT8 * numVariables;
1852 if (cursor() + len <= length()) {
1854 d_buffer + cursor(),
1855 numVariables);
1856 d_cursor += len;
1857 }
1858 else {
1859 invalidate();
1860 }
1861
1862 return *this;
1863}
1864
1865inline
1867 int numVariables)
1868{
1869 BSLS_ASSERT_SAFE(variables);
1870 BSLS_ASSERT_SAFE(0 <= numVariables);
1871
1872 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
1873}
1874
1875inline
1876ByteInStream& ByteInStream::getArrayUint8(char *variables, int numVariables)
1877{
1878 BSLS_ASSERT_SAFE(variables);
1879 BSLS_ASSERT_SAFE(0 <= numVariables);
1880
1881 return getArrayInt8(variables, numVariables);
1882}
1883
1884inline
1886 int numVariables)
1887{
1888 BSLS_ASSERT_SAFE(variables);
1889 BSLS_ASSERT_SAFE(0 <= numVariables);
1890
1891 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
1892}
1893
1894 // *** arrays of floating-point values ***
1895
1896inline
1898 int numVariables)
1899{
1900 BSLS_ASSERT_SAFE(variables);
1901 BSLS_ASSERT_SAFE(0 <= numVariables);
1902
1905 return *this; // RETURN
1906 }
1907
1908 const int len = MarshallingUtil::k_SIZEOF_FLOAT64 * numVariables;
1909 if (cursor() + len <= length()) {
1911 d_buffer + cursor(),
1912 numVariables);
1913 d_cursor += len;
1914 }
1915 else {
1916 invalidate();
1917 }
1918
1919 return *this;
1920}
1921
1922inline
1923ByteInStream& ByteInStream::getArrayFloat32(float *variables, int numVariables)
1924{
1925 BSLS_ASSERT_SAFE(variables);
1926 BSLS_ASSERT_SAFE(0 <= numVariables);
1927
1930 return *this; // RETURN
1931 }
1932
1933 const int len = MarshallingUtil::k_SIZEOF_FLOAT32 * numVariables;
1934 if (cursor() + len <= length()) {
1936 d_buffer + cursor(),
1937 numVariables);
1938 d_cursor += len;
1939 }
1940 else {
1941 invalidate();
1942 }
1943
1944 return *this;
1945}
1946
1947// ACCESSORS
1948inline
1949ByteInStream::operator const void *() const
1950{
1951 return isValid() ? this : 0;
1952}
1953
1954inline
1955bsl::size_t ByteInStream::cursor() const
1956{
1957 return d_cursor;
1958}
1959
1960inline
1961const char *ByteInStream::data() const
1962{
1963 return d_numBytes ? d_buffer : 0;
1964}
1965
1966inline
1968{
1969 return cursor() == length();
1970}
1971
1972inline
1974{
1975 return d_validFlag;
1976}
1977
1978inline
1979bsl::size_t ByteInStream::length() const
1980{
1981 return d_numBytes;
1982}
1983
1984template <class TYPE>
1985inline
1987{
1988 return InStreamFunctions::bdexStreamIn(stream, value);
1989}
1990
1991} // close package namespace
1992
1993
1994#endif
1995
1996// ----------------------------------------------------------------------------
1997// Copyright 2014 Bloomberg Finance L.P.
1998//
1999// Licensed under the Apache License, Version 2.0 (the "License");
2000// you may not use this file except in compliance with the License.
2001// You may obtain a copy of the License at
2002//
2003// http://www.apache.org/licenses/LICENSE-2.0
2004//
2005// Unless required by applicable law or agreed to in writing, software
2006// distributed under the License is distributed on an "AS IS" BASIS,
2007// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2008// See the License for the specific language governing permissions and
2009// limitations under the License.
2010// ----------------------------- END-OF-FILE ----------------------------------
2011
2012/** @} */
2013/** @} */
2014/** @} */
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 bslstl_stringref.h:372
const CHAR_TYPE * data() const
Definition bslstl_stringref.h:936
size_type length() const
Definition bslstl_stringref.h:958
Definition bslx_byteinstream.h:394
ByteInStream & getArrayInt40(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1636
ByteInStream & getFloat64(double &variable)
Definition bslx_byteinstream.h:1396
ByteInStream & getInt8(char &variable)
Definition bslx_byteinstream.h:1357
ByteInStream & getInt56(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1129
bsl::size_t cursor() const
Return the index of the next byte to be extracted from this stream.
Definition bslx_byteinstream.h:1955
bool isEmpty() const
Definition bslx_byteinstream.h:1967
ByteInStream & getArrayUint16(unsigned short *variables, int numVariables)
Definition bslx_byteinstream.h:1815
bsl::size_t length() const
Definition bslx_byteinstream.h:1979
ByteInStream & getInt40(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1205
ByteInStream & getArrayInt64(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1480
ByteInStream & getUint8(char &variable)
Definition bslx_byteinstream.h:1382
ByteInStream & getUint16(unsigned short &variable)
Definition bslx_byteinstream.h:1338
ByteInStream & getUint48(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1186
ByteInStream & getUint64(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1110
ByteInStream & getUint24(unsigned int &variable)
Definition bslx_byteinstream.h:1300
ByteInStream & getUint40(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1224
ByteInStream & getArrayInt24(int *variables, int numVariables)
Definition bslx_byteinstream.h:1739
ByteInStream & getArrayInt16(short *variables, int numVariables)
Definition bslx_byteinstream.h:1790
ByteInStream & getArrayInt56(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1532
ByteInStream & getLength(int &length)
Definition bslx_byteinstream.h:1009
ByteInStream()
Definition bslx_byteinstream.h:975
ByteInStream & getInt48(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1167
ByteInStream & getArrayUint24(unsigned int *variables, int numVariables)
Definition bslx_byteinstream.h:1764
void reset()
Definition bslx_byteinstream.h:1062
ByteInStream & getArrayFloat64(double *variables, int numVariables)
Definition bslx_byteinstream.h:1897
ByteInStream & getArrayInt48(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1584
ByteInStream & getArrayUint32(unsigned int *variables, int numVariables)
Definition bslx_byteinstream.h:1713
ByteInStream & getArrayUint56(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1558
ByteInStream & getArrayFloat32(float *variables, int numVariables)
Definition bslx_byteinstream.h:1923
ByteInStream & getArrayUint8(char *variables, int numVariables)
Definition bslx_byteinstream.h:1876
bool isValid() const
Definition bslx_byteinstream.h:1973
ByteInStream & getArrayInt8(char *variables, int numVariables)
Definition bslx_byteinstream.h:1841
friend bsl::ostream & operator<<(bsl::ostream &stream, const ByteInStream &object)
ByteInStream & getInt32(int &variable)
Definition bslx_byteinstream.h:1243
ByteInStream & getArrayInt32(int *variables, int numVariables)
Definition bslx_byteinstream.h:1688
void invalidate()
Definition bslx_byteinstream.h:1056
ByteInStream & getArrayUint64(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1506
ByteInStream & getArrayUint48(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1610
~ByteInStream()
Destroy this object.
Definition bslx_byteinstream.h:1003
ByteInStream & getInt64(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1091
ByteInStream & getFloat32(float &variable)
Definition bslx_byteinstream.h:1415
ByteInStream & getInt16(short &variable)
Definition bslx_byteinstream.h:1319
ByteInStream & getArrayUint40(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1662
ByteInStream & getString(bsl::string &variable)
Definition bslx_byteinstream.h:1436
ByteInStream & getUint32(unsigned int &variable)
Definition bslx_byteinstream.h:1262
ByteInStream & getUint56(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1148
ByteInStream & getInt24(int &variable)
Definition bslx_byteinstream.h:1281
ByteInStream & getVersion(int &version)
Definition bslx_byteinstream.h:1041
const char * data() const
Definition bslx_byteinstream.h:1961
#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
bsl::ostream & operator<<(bsl::ostream &stream, const ByteInStream &object)
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
static void getArrayFloat64(double *variables, const char *buffer, int numVariables)
static void getArrayInt24(int *variables, const char *buffer, int numVariables)
static void getUint24(unsigned int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1291
static void getInt56(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1072
static void getInt32(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1222
static void getFloat32(float *variable, const char *buffer)
Definition bslx_marshallingutil.h:1412
static void getArrayUint48(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void getArrayFloat32(float *variables, const char *buffer, int numVariables)
static void getUint16(unsigned short *variable, const char *buffer)
Definition bslx_marshallingutil.h:1335
static void getUint64(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1043
static void getInt40(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1174
static void getUint56(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1098
static void getInt64(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1014
static void getArrayInt56(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
@ k_SIZEOF_INT8
Definition bslx_marshallingutil.h:279
@ k_SIZEOF_INT48
Definition bslx_marshallingutil.h:274
@ k_SIZEOF_FLOAT64
Definition bslx_marshallingutil.h:280
@ k_SIZEOF_INT64
Definition bslx_marshallingutil.h:272
@ k_SIZEOF_INT24
Definition bslx_marshallingutil.h:277
@ k_SIZEOF_INT56
Definition bslx_marshallingutil.h:273
@ k_SIZEOF_INT16
Definition bslx_marshallingutil.h:278
@ k_SIZEOF_FLOAT32
Definition bslx_marshallingutil.h:281
@ k_SIZEOF_INT40
Definition bslx_marshallingutil.h:275
@ k_SIZEOF_INT32
Definition bslx_marshallingutil.h:276
static void getArrayInt32(int *variables, const char *buffer, int numVariables)
static void getArrayUint64(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void getArrayInt48(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
static void getArrayInt8(char *variables, const char *buffer, int numVariables)
Definition bslx_marshallingutil.h:1474
static void getArrayUint56(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void getArrayUint16(unsigned short *variables, const char *buffer, int numVariables)
static void getInt16(short *variable, const char *buffer)
Definition bslx_marshallingutil.h:1312
static void getArrayUint32(unsigned int *variables, const char *buffer, int numVariables)
static void getFloat64(double *variable, const char *buffer)
Definition bslx_marshallingutil.h:1386
static void getArrayInt64(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
static void getUint48(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1149
static void getInt24(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1270
static void getArrayInt40(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
static void getArrayInt16(short *variables, const char *buffer, int numVariables)
static void getUint40(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1198
static void getInt48(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1124
static void getUint32(unsigned int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1246
static void getArrayUint40(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void getInt8(char *variable, const char *buffer)
Definition bslx_marshallingutil.h:1357
static void getArrayUint24(unsigned int *variables, const char *buffer, int numVariables)