BDE 4.39.x 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`.
389///
390/// \note Note that attempting to read beyond the end of a stream will automatically
391/// invalidate the stream. See the `bslx` package-level documentation for
392/// the definition of the BDEX `InStream` protocol.
393///
394/// See @ref bslx_byteinstream
396
397 // DATA
398 const char *d_buffer; // bytes to be unexternalized
399
400 bsl::size_t d_numBytes; // number of bytes in 'd_buffer'
401
402 bool d_validFlag; // stream validity flag; 'true' if stream is in
403 // valid state, 'false' otherwise
404
405 bsl::size_t d_cursor; // index of the next byte to be extracted from
406 // this stream
407
408 // FRIENDS
409 friend bsl::ostream& operator<<(bsl::ostream& stream,
410 const ByteInStream& object);
411
412 private:
413 // NOT IMPLEMENTED
415 ByteInStream& operator=(const ByteInStream&);
416
417 public:
418 // CREATORS
419
420 /// Create an empty input byte stream.
421 /// \note Note that the constructed object
422 /// is useless until a buffer is set with the `reset` method.
423 explicit ByteInStream();
424
425 /// Create an input byte stream containing the specified initial
426 /// `numBytes` from the specified `buffer`.
427 ///
428 /// \pre The behavior is undefined unless `0 == numBytes` if `0 == buffer`.
429 ByteInStream(const char *buffer, bsl::size_t numBytes);
430
431 /// Create an input byte stream containing the specified `srcData`.
432 explicit ByteInStream(const bslstl::StringRef& srcData);
433
434 /// Destroy this object.
436
437 // MANIPULATORS
438
439 /// If the most-significant bit of the one byte of this stream at the
440 /// current cursor location is set, assign to the specified `length` the
441 /// four-byte, two's complement integer (in host byte order) comprised
442 /// of the four bytes of this stream at the current cursor location (in
443 /// network byte order) with the most-significant bit unset; otherwise,
444 /// assign to `length` the one-byte, two's complement integer comprised
445 /// of the one byte of this stream at the current cursor location.
446 /// Update the cursor location and return a reference to this stream.
447 /// If this stream is initially invalid, this operation has no effect.
448 /// If this function otherwise fails to extract a valid value, this
449 /// stream is marked invalid and the value of `length` is undefined.
450 ///
451 /// \note Note that the value will be zero-extended.
453
454 /// Assign to the specified `version` the one-byte, two's complement
455 /// unsigned integer comprised of the one byte of this stream at the
456 /// current cursor location, update the cursor location, and return a
457 /// reference to this stream. If this stream is initially invalid, this
458 /// operation has no effect. If this function otherwise fails to
459 /// extract a valid value, this stream is marked invalid and the value of `version` is undefined.
460 ///
461 /// \note Note that the value will be
462 /// zero-extended.
463 ByteInStream& getVersion(int& version);
464
465 /// Put this input stream in an invalid state. This function has no effect if this stream is already invalid.
466 ///
467 /// \note Note that this function
468 /// should be called whenever a value extracted from this stream is
469 /// determined to be invalid, inconsistent, or otherwise incorrect.
470 void invalidate();
471
472 /// Set the index of the next byte to be extracted from this stream to 0
473 /// (i.e., the beginning of the stream) and validate this stream if it
474 /// is currently invalid.
475 void reset();
476
477 /// Reset this stream to extract from the specified `buffer` containing
478 /// the specified `numBytes`, set the index of the next byte to be
479 /// extracted to 0 (i.e., the beginning of the stream), and validate
480 /// this stream if it is currently invalid.
481 ///
482 /// \pre The behavior is undefined unless `0 == numBytes` if `0 == buffer`.
483 void reset(const char *buffer, bsl::size_t numBytes);
484
485 /// Reset this stream to extract from the specified `srcData`, set the
486 /// index of the next byte to be extracted to 0 (i.e., the beginning of
487 /// the stream), and validate this stream if it is currently invalid.
488 void reset(const bslstl::StringRef& srcData);
489
490 // *** scalar integer values ***
491
492 /// Assign to the specified `variable` the eight-byte, two's complement
493 /// integer (in host byte order) comprised of the eight bytes of this
494 /// stream at the current cursor location (in network byte order),
495 /// update the cursor location, and return a reference to this stream.
496 /// If this stream is initially invalid, this operation has no effect.
497 /// If this function otherwise fails to extract a valid value, this
498 /// stream is marked invalid and the value of `variable` is undefined.
499 ///
500 /// \note Note that the value will be sign-extended.
502
503 /// Assign to the specified `variable` the eight-byte, two's complement
504 /// unsigned integer (in host byte order) comprised of the eight bytes
505 /// of this stream at the current cursor location (in network byte
506 /// order), update the cursor location, and return a reference to this
507 /// stream. If this stream is initially invalid, this operation has no
508 /// effect. If this function otherwise fails to extract a valid value,
509 /// this stream is marked invalid and the value of `variable` is undefined.
510 ///
511 /// \note Note that the value will be zero-extended.
513
514 /// Assign to the specified `variable` the seven-byte, two's complement
515 /// integer (in host byte order) comprised of the seven bytes of this
516 /// stream at the current cursor location (in network byte order),
517 /// update the cursor location, and return a reference to this stream.
518 /// If this stream is initially invalid, this operation has no effect.
519 /// If this function otherwise fails to extract a valid value, this
520 /// stream is marked invalid and the value of `variable` is undefined.
521 ///
522 /// \note Note that the value will be sign-extended.
524
525 /// Assign to the specified `variable` the seven-byte, two's complement
526 /// unsigned integer (in host byte order) comprised of the seven bytes
527 /// of this stream at the current cursor location (in network byte
528 /// order), update the cursor location, and return a reference to this
529 /// stream. If this stream is initially invalid, this operation has no
530 /// effect. If this function otherwise fails to extract a valid value,
531 /// this stream is marked invalid and the value of `variable` is undefined.
532 ///
533 /// \note Note that the value will be zero-extended.
535
536 /// Assign to the specified `variable` the six-byte, two's complement
537 /// integer (in host byte order) comprised of the six bytes of this
538 /// stream at the current cursor location (in network byte order),
539 /// update the cursor location, and return a reference to this stream.
540 /// If this stream is initially invalid, this operation has no effect.
541 /// If this function otherwise fails to extract a valid value, this
542 /// stream is marked invalid and the value of `variable` is undefined.
543 ///
544 /// \note Note that the value will be sign-extended.
546
547 /// Assign to the specified `variable` the six-byte, two's complement
548 /// unsigned integer (in host byte order) comprised of the six bytes of
549 /// this stream at the current cursor location (in network byte order),
550 /// update the cursor location, and return a reference to this stream.
551 /// If this stream is initially invalid, this operation has no effect.
552 /// If this function otherwise fails to extract a valid value, this
553 /// stream is marked invalid and the value of `variable` is undefined.
554 ///
555 /// \note Note that the value will be zero-extended.
557
558 /// Assign to the specified `variable` the five-byte, two's complement
559 /// integer (in host byte order) comprised of the five bytes of this
560 /// stream at the current cursor location (in network byte order),
561 /// update the cursor location, and return a reference to this stream.
562 /// If this stream is initially invalid, this operation has no effect.
563 /// If this function otherwise fails to extract a valid value, this
564 /// stream is marked invalid and the value of `variable` is undefined.
565 ///
566 /// \note Note that the value will be sign-extended.
568
569 /// Assign to the specified `variable` the five-byte, two's complement
570 /// unsigned integer (in host byte order) comprised of the five bytes of
571 /// this stream at the current cursor location (in network byte order),
572 /// update the cursor location, and return a reference to this stream.
573 /// If this stream is initially invalid, this operation has no effect.
574 /// If this function otherwise fails to extract a valid value, this
575 /// stream is marked invalid and the value of `variable` is undefined.
576 ///
577 /// \note Note that the value will be zero-extended.
579
580 /// Assign to the specified `variable` the four-byte, two's complement
581 /// integer (in host byte order) comprised of the four bytes of this
582 /// stream at the current cursor location (in network byte order),
583 /// update the cursor location, and return a reference to this stream.
584 /// If this stream is initially invalid, this operation has no effect.
585 /// If this function otherwise fails to extract a valid value, this
586 /// stream is marked invalid and the value of `variable` is undefined.
587 ///
588 /// \note Note that the value will be sign-extended.
589 ByteInStream& getInt32(int& variable);
590
591 /// Assign to the specified `variable` the four-byte, two's complement
592 /// unsigned integer (in host byte order) comprised of the four bytes of
593 /// this stream at the current cursor location (in network byte order),
594 /// update the cursor location, and return a reference to this stream.
595 /// If this stream is initially invalid, this operation has no effect.
596 /// If this function otherwise fails to extract a valid value, this
597 /// stream is marked invalid and the value of `variable` is undefined.
598 ///
599 /// \note Note that the value will be zero-extended.
600 ByteInStream& getUint32(unsigned int& variable);
601
602 /// Assign to the specified `variable` the three-byte, two's complement
603 /// integer (in host byte order) comprised of the three bytes of this
604 /// stream at the current cursor location (in network byte order),
605 /// update the cursor location, and return a reference to this stream.
606 /// If this stream is initially invalid, this operation has no effect.
607 /// If this function otherwise fails to extract a valid value, this
608 /// stream is marked invalid and the value of `variable` is undefined.
609 ///
610 /// \note Note that the value will be sign-extended.
611 ByteInStream& getInt24(int& variable);
612
613 /// Assign to the specified `variable` the three-byte, two's complement
614 /// unsigned integer (in host byte order) comprised of the three bytes
615 /// of this stream at the current cursor location (in network byte
616 /// order), update the cursor location, and return a reference to this
617 /// stream. If this stream is initially invalid, this operation has no
618 /// effect. If this function otherwise fails to extract a valid value,
619 /// this stream is marked invalid and the value of `variable` is undefined.
620 ///
621 /// \note Note that the value will be zero-extended.
622 ByteInStream& getUint24(unsigned int& variable);
623
624 /// Assign to the specified `variable` the two-byte, two's complement
625 /// integer (in host byte order) comprised of the two bytes of this
626 /// stream at the current cursor location (in network byte order),
627 /// update the cursor location, and return a reference to this stream.
628 /// If this stream is initially invalid, this operation has no effect.
629 /// If this function otherwise fails to extract a valid value, this
630 /// stream is marked invalid and the value of `variable` is undefined.
631 ///
632 /// \note Note that the value will be sign-extended.
633 ByteInStream& getInt16(short& variable);
634
635 /// Assign to the specified `variable` the two-byte, two's complement
636 /// unsigned integer (in host byte order) comprised of the two bytes of
637 /// this stream at the current cursor location (in network byte order),
638 /// update the cursor location, and return a reference to this stream.
639 /// If this stream is initially invalid, this operation has no effect.
640 /// If this function otherwise fails to extract a valid value, this
641 /// stream is marked invalid and the value of `variable` is undefined.
642 ///
643 /// \note Note that the value will be zero-extended.
644 ByteInStream& getUint16(unsigned short& variable);
645
646 /// Assign to the specified `variable` the one-byte, two's complement
647 /// integer comprised of the one byte of this stream at the current
648 /// cursor location, update the cursor location, and return a reference
649 /// to this stream. If this stream is initially invalid, this operation
650 /// has no effect. If this function otherwise fails to extract a valid
651 /// value, this stream is marked invalid and the value of `variable` is undefined.
652 ///
653 /// \note Note that the value will be sign-extended.
654 ByteInStream& getInt8(char& variable);
655 ByteInStream& getInt8(signed char& variable);
656
657 /// Assign to the specified `variable` the one-byte, two's complement
658 /// unsigned integer comprised of the one byte of this stream at the
659 /// current cursor location, update the cursor location, and return a
660 /// reference to this stream. If this stream is initially invalid, this
661 /// operation has no effect. If this function otherwise fails to
662 /// extract a valid value, this stream is marked invalid and the value of `variable` is undefined.
663 ///
664 /// \note Note that the value will be
665 /// zero-extended.
666 ByteInStream& getUint8(char& variable);
667 ByteInStream& getUint8(unsigned char& variable);
668
669 // *** scalar floating-point values ***
670
671 /// Assign to the specified `variable` the eight-byte IEEE
672 /// double-precision floating-point number (in host byte order)
673 /// comprised of the eight bytes of this stream at the current cursor
674 /// location (in network byte order), update the cursor location, and
675 /// return a reference to this stream. If this stream is initially
676 /// invalid, this operation has no effect. If this function otherwise
677 /// fails to extract a valid value, this stream is marked invalid and
678 /// the value of `variable` is undefined.
679 ByteInStream& getFloat64(double& variable);
680
681 /// Assign to the specified `variable` the four-byte IEEE
682 /// single-precision floating-point number (in host byte order)
683 /// comprised of the four bytes of this stream at the current cursor
684 /// location (in network byte order), update the cursor location, and
685 /// return a reference to this stream. If this stream is initially
686 /// invalid, this operation has no effect. If this function otherwise
687 /// fails to extract a valid value, this stream is marked invalid and
688 /// the value of `variable` is undefined.
689 ByteInStream& getFloat32(float& variable);
690
691 // *** string values ***
692
693 /// Assign to the specified `variable` the string comprised of the
694 /// length of the string (see `getLength`) and the string data (see
695 /// `getUint8`), update the cursor location, and return a reference to
696 /// this stream. If this stream is initially invalid, this operation
697 /// has no effect. If this function otherwise fails to extract a valid
698 /// value, this stream is marked invalid and the value of `variable` is
699 /// undefined.
701
702 // *** arrays of integer values ***
703
704 /// Assign to the specified `variables` the consecutive eight-byte,
705 /// two's complement integers (in host byte order) comprised of each of
706 /// the specified `numVariables` eight-byte sequences of this stream at
707 /// the current cursor location (in network byte order), update the
708 /// cursor location, and return a reference to this stream. If this
709 /// stream is initially invalid, this operation has no effect. If this
710 /// function otherwise fails to extract a valid value, this stream is
711 /// marked invalid and the value of `variables` is undefined.
712 ///
713 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
714 ///
715 /// \note Note that each of the values will be
716 /// sign-extended.
718 int numVariables);
719
720 /// Assign to the specified `variables` the consecutive eight-byte,
721 /// two's complement unsigned integers (in host byte order) comprised of
722 /// each of the specified `numVariables` eight-byte sequences of this
723 /// stream at the current cursor location (in network byte order),
724 /// update the cursor location, and return a reference to this stream.
725 /// If this stream is initially invalid, this operation has no effect.
726 /// If this function otherwise fails to extract a valid value, this
727 /// stream is marked invalid and the value of `variables` is undefined.
728 ///
729 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
730 ///
731 /// \note Note that each of the values will be
732 /// zero-extended.
734 int numVariables);
735
736 /// Assign to the specified `variables` the consecutive seven-byte,
737 /// two's complement integers (in host byte order) comprised of each of
738 /// the specified `numVariables` seven-byte sequences of this stream at
739 /// the current cursor location (in network byte order), update the
740 /// cursor location, and return a reference to this stream. If this
741 /// stream is initially invalid, this operation has no effect. If this
742 /// function otherwise fails to extract a valid value, this stream is
743 /// marked invalid and the value of `variables` is undefined.
744 ///
745 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
746 ///
747 /// \note Note that each of the values will be
748 /// sign-extended.
750 int numVariables);
751
752 /// Assign to the specified `variables` the consecutive seven-byte,
753 /// two's complement unsigned integers (in host byte order) comprised of
754 /// each of the specified `numVariables` seven-byte sequences of this
755 /// 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 `variables` is undefined.
760 ///
761 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
762 ///
763 /// \note Note that each of the values will be
764 /// zero-extended.
766 int numVariables);
767
768 /// Assign to the specified `variables` the consecutive six-byte, two's
769 /// complement integers (in host byte order) comprised of each of the
770 /// specified `numVariables` six-byte sequences of this stream at the
771 /// current cursor location (in network byte order), update the cursor
772 /// location, and return a reference to this stream. If this stream is
773 /// initially invalid, this operation has no effect. If this function
774 /// otherwise fails to extract a valid value, this stream is marked
775 /// invalid and the value of `variables` is undefined.
776 ///
777 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
778 ///
779 /// \note Note that each of the values will be sign-extended.
781 int numVariables);
782
783 /// Assign to the specified `variables` the consecutive six-byte, two's
784 /// complement unsigned integers (in host byte order) comprised of each
785 /// of the specified `numVariables` six-byte sequences of this stream at
786 /// the current cursor location (in network byte order), update the
787 /// cursor location, and return a reference to this stream. If this
788 /// stream is initially invalid, this operation has no effect. If this
789 /// function otherwise fails to extract a valid value, this stream is
790 /// marked invalid and the value of `variables` is undefined.
791 ///
792 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
793 ///
794 /// \note Note that each of the values will be
795 /// zero-extended.
797 int numVariables);
798
799 /// Assign to the specified `variables` the consecutive five-byte, two's
800 /// complement integers (in host byte order) comprised of each of the
801 /// specified `numVariables` five-byte sequences of this stream at the
802 /// current cursor location (in network byte order), update the cursor
803 /// location, and return a reference to this stream. If this stream is
804 /// initially invalid, this operation has no effect. If this function
805 /// otherwise fails to extract a valid value, this stream is marked
806 /// invalid and the value of `variables` is undefined.
807 ///
808 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
809 ///
810 /// \note Note that each of the values will be sign-extended.
812 int numVariables);
813
814 /// Assign to the specified `variables` the consecutive five-byte, two's
815 /// complement unsigned integers (in host byte order) comprised of each
816 /// of the specified `numVariables` five-byte sequences of this stream
817 /// at the current cursor location (in network byte order), update the
818 /// cursor location, and return a reference to this stream. If this
819 /// stream is initially invalid, this operation has no effect. If this
820 /// function otherwise fails to extract a valid value, this stream is
821 /// marked invalid and the value of `variables` is undefined.
822 ///
823 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
824 ///
825 /// \note Note that each of the values will be
826 /// zero-extended.
828 int numVariables);
829
830 /// Assign to the specified `variables` the consecutive four-byte, two's
831 /// complement integers (in host byte order) comprised of each of the
832 /// specified `numVariables` four-byte sequences of this stream at the
833 /// current cursor location (in network byte order), update the cursor
834 /// location, and return a reference to this stream. If this stream is
835 /// initially invalid, this operation has no effect. If this function
836 /// otherwise fails to extract a valid value, this stream is marked
837 /// invalid and the value of `variables` is undefined.
838 ///
839 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
840 ///
841 /// \note Note that each of the values will be sign-extended.
842 ByteInStream& getArrayInt32(int *variables, int numVariables);
843
844 /// Assign to the specified `variables` the consecutive four-byte, two's
845 /// complement unsigned integers (in host byte order) comprised of each
846 /// of the specified `numVariables` four-byte sequences of this stream
847 /// at the current cursor location (in network byte order), update the
848 /// cursor location, and return a reference to this stream. If this
849 /// stream is initially invalid, this operation has no effect. If this
850 /// function otherwise fails to extract a valid value, this stream is
851 /// marked invalid and the value of `variables` is undefined.
852 ///
853 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
854 ///
855 /// \note Note that each of the values will be
856 /// zero-extended.
857 ByteInStream& getArrayUint32(unsigned int *variables, int numVariables);
858
859 /// Assign to the specified `variables` the consecutive three-byte,
860 /// two's complement integers (in host byte order) comprised of each of
861 /// the specified `numVariables` three-byte sequences of this stream at
862 /// the current cursor location (in network byte order), update the
863 /// cursor location, and return a reference to this stream. If this
864 /// stream is initially invalid, this operation has no effect. If this
865 /// function otherwise fails to extract a valid value, this stream is
866 /// marked invalid and the value of `variables` is undefined.
867 ///
868 /// \pre The behavior is undefined unless `0 <= numValues` and `variables` has sufficient capacity.
869 ///
870 /// \note Note that each of the values will be
871 /// sign-extended.
872 ByteInStream& getArrayInt24(int *variables, int numVariables);
873
874 /// Assign to the specified `variables` the consecutive three-byte,
875 /// two's complement unsigned integers (in host byte order) comprised of
876 /// each of the specified `numVariables` three-byte sequences of this
877 /// stream at the current cursor location (in network byte order),
878 /// update the cursor location, and return a reference to this stream.
879 /// If this stream is initially invalid, this operation has no effect.
880 /// If this function otherwise fails to extract a valid value, this
881 /// stream is marked invalid and the value of `variables` is undefined.
882 ///
883 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
884 ///
885 /// \note Note that each of the values will be
886 /// zero-extended.
887 ByteInStream& getArrayUint24(unsigned int *variables, int numVariables);
888
889 /// Assign to the specified `variables` the consecutive two-byte, two's
890 /// complement integers (in host byte order) comprised of each of the
891 /// specified `numVariables` two-byte sequences of this stream at the
892 /// current cursor location (in network byte order), update the cursor
893 /// location, and return a reference to this stream. If this stream is
894 /// initially invalid, this operation has no effect. If this function
895 /// otherwise fails to extract a valid value, this stream is marked
896 /// invalid and the value of `variables` is undefined.
897 ///
898 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
899 ///
900 /// \note Note that each of the values will be sign-extended.
901 ByteInStream& getArrayInt16(short *variables, int numVariables);
902
903 /// Assign to the specified `variables` the consecutive two-byte, two's
904 /// complement unsigned integers (in host byte order) comprised of each
905 /// of the specified `numVariables` two-byte sequences of this stream at
906 /// the current cursor location (in network byte order), update the
907 /// cursor location, and return a reference to this stream. If this
908 /// stream is initially invalid, this operation has no effect. If this
909 /// function otherwise fails to extract a valid value, this stream is
910 /// marked invalid and the value of `variables` is undefined.
911 ///
912 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
913 ///
914 /// \note Note that each of the values will be
915 /// zero-extended.
916 ByteInStream& getArrayUint16(unsigned short *variables, int numVariables);
917
918 /// Assign to the specified `variables` the consecutive one-byte, two's
919 /// complement integers comprised of each of the specified
920 /// `numVariables` one-byte sequences of this stream at the current
921 /// cursor location, update the cursor location, and return a reference
922 /// to this stream. If this stream is initially invalid, this operation
923 /// has no effect. If this function otherwise fails to extract a valid
924 /// value, this stream is marked invalid and the value of `variables` is undefined.
925 ///
926 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
927 ///
928 /// \note Note that each of the values
929 /// will be sign-extended.
930 ByteInStream& getArrayInt8(char *variables, int numVariables);
931 ByteInStream& getArrayInt8(signed char *variables, int numVariables);
932
933 /// Assign to the specified `variables` the consecutive one-byte, two's
934 /// complement unsigned integers comprised of each of the specified
935 /// `numVariables` one-byte sequences of this stream at the current
936 /// cursor location, update the cursor location, and return a reference
937 /// to this stream. If this stream is initially invalid, this operation
938 /// has no effect. If this function otherwise fails to extract a valid
939 /// value, this stream is marked invalid and the value of `variables` is undefined.
940 ///
941 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
942 ///
943 /// \note Note that each of the values
944 /// will be zero-extended.
945 ByteInStream& getArrayUint8(char *variables, int numVariables);
946 ByteInStream& getArrayUint8(unsigned char *variables, int numVariables);
947
948 // *** arrays of floating-point values ***
949
950 /// Assign to the specified `variables` the consecutive eight-byte IEEE
951 /// double-precision floating-point numbers (in host byte order)
952 /// comprised of each of the specified `numVariables` eight-byte
953 /// sequences of this stream at the current cursor location (in network
954 /// byte order), update the cursor location, and return a reference to
955 /// this stream. If this stream is initially invalid, this operation
956 /// has no effect. If this function otherwise fails to extract a valid
957 /// value, this stream is marked invalid and the value of `variables` is undefined.
958 ///
959 /// \pre The behavior is undefined unless `0 <= numVariables` and
960 /// `variables` has sufficient capacity.
961 ByteInStream& getArrayFloat64(double *variables, int numVariables);
962
963 /// Assign to the specified `variables` the consecutive four-byte IEEE
964 /// single-precision floating-point numbers (in host byte order)
965 /// comprised of each of the specified `numVariables` four-byte
966 /// sequences of this stream at the current cursor location (in network
967 /// byte order), update the cursor location, and return a reference to
968 /// this stream. If this stream is initially invalid, this operation
969 /// has no effect. If this function otherwise fails to extract a valid
970 /// value, this stream is marked invalid and the value of `variables` is undefined.
971 ///
972 /// \pre The behavior is undefined unless `0 <= numVariables` and
973 /// `variables` has sufficient capacity.
974 ByteInStream& getArrayFloat32(float *variables, int numVariables);
975
976 // ACCESSORS
977
978 /// Return a non-zero value if this stream is valid, and 0 otherwise.
979 /// An invalid stream is a stream for which an input operation was
980 /// detected to have failed.
981 operator const void *() const;
982
983 /// Return the index of the next byte to be extracted from this stream.
984 bsl::size_t cursor() const;
985
986 /// Return the address of the contiguous, non-modifiable external memory
987 /// buffer of this stream. The behavior of accessing elements outside
988 /// the range `[ data() .. data() + (length() - 1) ]` is undefined.
989 const char *data() const;
990
991 /// Return `true` if this stream is empty, and `false` otherwise.
992 ///
993 /// \note Note that this function enables higher-level types to verify that, after
994 /// successfully reading all expected data, no data remains.
995 bool isEmpty() const;
996
997 /// Return `true` if this stream is valid, and `false` otherwise. An
998 /// invalid stream is a stream in which insufficient or invalid data was detected during an extraction operation.
999 ///
1000 /// \note Note that an empty stream
1001 /// will be valid unless an extraction attempt or explicit invalidation
1002 /// causes it to be otherwise.
1003 bool isValid() const;
1004
1005 /// Return the total number of bytes stored in the external memory
1006 /// buffer.
1007 bsl::size_t length() const;
1008};
1009
1010// FREE OPERATORS
1011
1012/// Write the specified `object` to the specified output `stream` in some
1013/// reasonable (multi-line) format, and return a reference to `stream`.
1014bsl::ostream& operator<<(bsl::ostream& stream,
1015 const ByteInStream& object);
1016
1017/// Read the specified `value` from the specified input `stream` following
1018/// the requirements of the BDEX protocol (see the `bslx` package-level
1019/// documentation), and return a reference to `stream`.
1020///
1021/// \pre The behavior is undefined unless `TYPE` is BDEX-compliant.
1022template <class TYPE>
1023ByteInStream& operator>>(ByteInStream& stream, TYPE& value);
1024
1025// ============================================================================
1026// INLINE DEFINITIONS
1027// ============================================================================
1028
1029 // ------------------
1030 // class ByteInStream
1031 // ------------------
1032
1033// CREATORS
1034inline
1036: d_buffer(0)
1037, d_numBytes(0)
1038, d_validFlag(true)
1039, d_cursor(0)
1040{
1041}
1042
1043inline
1044ByteInStream::ByteInStream(const char *buffer, bsl::size_t numBytes)
1045: d_buffer(buffer)
1046, d_numBytes(numBytes)
1047, d_validFlag(true)
1048, d_cursor(0)
1049{
1050 BSLS_ASSERT_SAFE(buffer || 0 == numBytes);
1051}
1052
1053inline
1055: d_buffer(srcData.data())
1056, d_numBytes(static_cast<int>(srcData.length()))
1057, d_validFlag(true)
1058, d_cursor(0)
1059{
1060}
1061
1062inline
1066
1067// MANIPULATORS
1068inline
1070{
1073 return *this; // RETURN
1074 }
1075
1077 if (127 < static_cast<unsigned char>(d_buffer[cursor()])) {
1078 // If 'length > 127', 'length' is stored as 4 bytes with top bit
1079 // set.
1080
1082 length &= 0x7fffffff; // Clear top bit.
1083 }
1084 else {
1085 // If 'length <= 127', 'length' is stored as one byte.
1086
1087 char tmp;
1090 length = tmp;
1091 }
1092 }
1093 else {
1094 invalidate();
1095 }
1096
1097 return *this;
1098}
1099
1100inline
1102{
1105 return *this; // RETURN
1106 }
1107
1108 unsigned char tmp = 0;
1109 getUint8(tmp);
1110 version = tmp;
1111
1112 return *this;
1113}
1114
1115inline
1117{
1118 d_validFlag = false;
1119}
1120
1121inline
1123{
1124 d_validFlag = true;
1125 d_cursor = 0;
1126}
1127
1128inline
1129void ByteInStream::reset(const char *buffer, bsl::size_t numBytes)
1130{
1131 BSLS_ASSERT_SAFE(buffer || 0 == numBytes);
1132
1133 d_buffer = buffer;
1134 d_numBytes = numBytes;
1135 d_validFlag = true;
1136 d_cursor = 0;
1137}
1138
1139inline
1141{
1142 d_buffer = srcData.data();
1143 d_numBytes = srcData.length();
1144 d_validFlag = true;
1145 d_cursor = 0;
1146}
1147
1148 // *** scalar integer values ***
1149
1150inline
1152{
1155 return *this; // RETURN
1156 }
1157
1159 MarshallingUtil::getInt64(&variable, d_buffer + cursor());
1161 }
1162 else {
1163 invalidate();
1164 }
1165
1166 return *this;
1167}
1168
1169inline
1171{
1174 return *this; // RETURN
1175 }
1176
1178 MarshallingUtil::getUint64(&variable, d_buffer + cursor());
1180 }
1181 else {
1182 invalidate();
1183 }
1184
1185 return *this;
1186}
1187
1188inline
1190{
1193 return *this; // RETURN
1194 }
1195
1197 MarshallingUtil::getInt56(&variable, d_buffer + cursor());
1199 }
1200 else {
1201 invalidate();
1202 }
1203
1204 return *this;
1205}
1206
1207inline
1209{
1212 return *this; // RETURN
1213 }
1214
1216 MarshallingUtil::getUint56(&variable, d_buffer + cursor());
1218 }
1219 else {
1220 invalidate();
1221 }
1222
1223 return *this;
1224}
1225
1226inline
1228{
1231 return *this; // RETURN
1232 }
1233
1235 MarshallingUtil::getInt48(&variable, d_buffer + cursor());
1237 }
1238 else {
1239 invalidate();
1240 }
1241
1242 return *this;
1243}
1244
1245inline
1247{
1250 return *this; // RETURN
1251 }
1252
1254 MarshallingUtil::getUint48(&variable, d_buffer + cursor());
1256 }
1257 else {
1258 invalidate();
1259 }
1260
1261 return *this;
1262}
1263
1264inline
1266{
1269 return *this; // RETURN
1270 }
1271
1273 MarshallingUtil::getInt40(&variable, d_buffer + cursor());
1275 }
1276 else {
1277 invalidate();
1278 }
1279
1280 return *this;
1281}
1282
1283inline
1285{
1288 return *this; // RETURN
1289 }
1290
1292 MarshallingUtil::getUint40(&variable, d_buffer + cursor());
1294 }
1295 else {
1296 invalidate();
1297 }
1298
1299 return *this;
1300}
1301
1302inline
1304{
1307 return *this; // RETURN
1308 }
1309
1311 MarshallingUtil::getInt32(&variable, d_buffer + cursor());
1313 }
1314 else {
1315 invalidate();
1316 }
1317
1318 return *this;
1319}
1320
1321inline
1323{
1326 return *this; // RETURN
1327 }
1328
1330 MarshallingUtil::getUint32(&variable, d_buffer + cursor());
1332 }
1333 else {
1334 invalidate();
1335 }
1336
1337 return *this;
1338}
1339
1340inline
1342{
1345 return *this; // RETURN
1346 }
1347
1349 MarshallingUtil::getInt24(&variable, d_buffer + cursor());
1351 }
1352 else {
1353 invalidate();
1354 }
1355
1356 return *this;
1357}
1358
1359inline
1361{
1364 return *this; // RETURN
1365 }
1366
1368 MarshallingUtil::getUint24(&variable, d_buffer + cursor());
1370 }
1371 else {
1372 invalidate();
1373 }
1374
1375 return *this;
1376}
1377
1378inline
1380{
1383 return *this; // RETURN
1384 }
1385
1387 MarshallingUtil::getInt16(&variable, d_buffer + cursor());
1389 }
1390 else {
1391 invalidate();
1392 }
1393
1394 return *this;
1395}
1396
1397inline
1398ByteInStream& ByteInStream::getUint16(unsigned short& variable)
1399{
1402 return *this; // RETURN
1403 }
1404
1406 MarshallingUtil::getUint16(&variable, d_buffer + cursor());
1408 }
1409 else {
1410 invalidate();
1411 }
1412
1413 return *this;
1414}
1415
1416inline
1418{
1421 return *this; // RETURN
1422 }
1423
1425 MarshallingUtil::getInt8(&variable, data() + cursor());
1427 }
1428 else {
1429 invalidate();
1430 }
1431
1432 return *this;
1433}
1434
1435inline
1437{
1438 return getInt8(reinterpret_cast<char&>(variable));
1439}
1440
1441inline
1443{
1444 return getInt8(variable);
1445}
1446
1447inline
1448ByteInStream& ByteInStream::getUint8(unsigned char& variable)
1449{
1450 return getInt8(reinterpret_cast<char&>(variable));
1451}
1452
1453 // *** scalar floating-point values ***
1454
1455inline
1457{
1460 return *this; // RETURN
1461 }
1462
1464 MarshallingUtil::getFloat64(&variable, d_buffer + cursor());
1466 }
1467 else {
1468 invalidate();
1469 }
1470
1471 return *this;
1472}
1473
1474inline
1476{
1479 return *this; // RETURN
1480 }
1481
1483 MarshallingUtil::getFloat32(&variable, d_buffer + cursor());
1485 }
1486 else {
1487 invalidate();
1488 }
1489
1490 return *this;
1491}
1492
1493 // *** string values ***
1494
1495inline
1497{
1500 return *this; // RETURN
1501 }
1502
1503 int length;
1507
1508 return *this; // RETURN
1509 }
1510 BSLS_ASSERT(0 <= length);
1511
1512 // 'length' could be corrupt or invalid, so we limit the initial 'resize'
1513 // to something that can accommodate the preponderance of strings that will
1514 // arise in practice. The remaining portion of a string longer than 16M is
1515 // read in via a second pass.
1516
1517 enum { k_INITIAL_ALLOCATION_SIZE = 16 * 1024 * 1024 };
1518
1519 const int initialLength = length < k_INITIAL_ALLOCATION_SIZE
1520 ? length
1521 : k_INITIAL_ALLOCATION_SIZE;
1522
1523 variable.resize(initialLength);
1524
1525 if (0 == length) {
1526 return *this; // RETURN
1527 }
1528
1529 getArrayUint8(&variable.front(), initialLength);
1530 if (isValid() && length > initialLength) {
1531 variable.resize(length);
1532 getArrayUint8(&variable[initialLength], length - initialLength);
1533 }
1534
1535 return *this;
1536}
1537
1538 // *** arrays of integer values ***
1539
1540inline
1542 int numVariables)
1543{
1544 BSLS_ASSERT_SAFE(variables);
1545 BSLS_ASSERT_SAFE(0 <= numVariables);
1546
1549 return *this; // RETURN
1550 }
1551
1552 const int len = MarshallingUtil::k_SIZEOF_INT64 * numVariables;
1553 if (cursor() + len <= length()) {
1555 d_buffer + cursor(),
1556 numVariables);
1557 d_cursor += len;
1558 }
1559 else {
1560 invalidate();
1561 }
1562
1563 return *this;
1564}
1565
1566inline
1568 int numVariables)
1569{
1570 BSLS_ASSERT_SAFE(variables);
1571 BSLS_ASSERT_SAFE(0 <= numVariables);
1572
1575 return *this; // RETURN
1576 }
1577
1578 const int len = MarshallingUtil::k_SIZEOF_INT64 * numVariables;
1579 if (cursor() + len <= length()) {
1581 d_buffer + cursor(),
1582 numVariables);
1583 d_cursor += len;
1584 }
1585 else {
1586 invalidate();
1587 }
1588
1589 return *this;
1590}
1591
1592inline
1594 int numVariables)
1595{
1596 BSLS_ASSERT_SAFE(variables);
1597 BSLS_ASSERT_SAFE(0 <= numVariables);
1598
1601 return *this; // RETURN
1602 }
1603
1604 const int len = MarshallingUtil::k_SIZEOF_INT56 * numVariables;
1605 if (cursor() + len <= length()) {
1607 d_buffer + cursor(),
1608 numVariables);
1609 d_cursor += len;
1610 }
1611 else {
1612 invalidate();
1613 }
1614
1615 return *this;
1616}
1617
1618inline
1620 int numVariables)
1621{
1622 BSLS_ASSERT_SAFE(variables);
1623 BSLS_ASSERT_SAFE(0 <= numVariables);
1624
1627 return *this; // RETURN
1628 }
1629
1630 const int len = MarshallingUtil::k_SIZEOF_INT56 * numVariables;
1631 if (cursor() + len <= length()) {
1633 d_buffer + cursor(),
1634 numVariables);
1635 d_cursor += len;
1636 }
1637 else {
1638 invalidate();
1639 }
1640
1641 return *this;
1642}
1643
1644inline
1646 int numVariables)
1647{
1648 BSLS_ASSERT_SAFE(variables);
1649 BSLS_ASSERT_SAFE(0 <= numVariables);
1650
1653 return *this; // RETURN
1654 }
1655
1656 const int len = MarshallingUtil::k_SIZEOF_INT48 * numVariables;
1657 if (cursor() + len <= length()) {
1659 d_buffer + cursor(),
1660 numVariables);
1661 d_cursor += len;
1662 }
1663 else {
1664 invalidate();
1665 }
1666
1667 return *this;
1668}
1669
1670inline
1672 int numVariables)
1673{
1674 BSLS_ASSERT_SAFE(variables);
1675 BSLS_ASSERT_SAFE(0 <= numVariables);
1676
1679 return *this; // RETURN
1680 }
1681
1682 const int len = MarshallingUtil::k_SIZEOF_INT48 * numVariables;
1683 if (cursor() + len <= length()) {
1685 d_buffer + cursor(),
1686 numVariables);
1687 d_cursor += len;
1688 }
1689 else {
1690 invalidate();
1691 }
1692
1693 return *this;
1694}
1695
1696inline
1698 int numVariables)
1699{
1700 BSLS_ASSERT_SAFE(variables);
1701 BSLS_ASSERT_SAFE(0 <= numVariables);
1702
1705 return *this; // RETURN
1706 }
1707
1708 const int len = MarshallingUtil::k_SIZEOF_INT40 * numVariables;
1709 if (cursor() + len <= length()) {
1711 d_buffer + cursor(),
1712 numVariables);
1713 d_cursor += len;
1714 }
1715 else {
1716 invalidate();
1717 }
1718
1719 return *this;
1720}
1721
1722inline
1724 int numVariables)
1725{
1726 BSLS_ASSERT_SAFE(variables);
1727 BSLS_ASSERT_SAFE(0 <= numVariables);
1728
1731 return *this; // RETURN
1732 }
1733
1734 const int len = MarshallingUtil::k_SIZEOF_INT40 * numVariables;
1735 if (cursor() + len <= length()) {
1737 d_buffer + cursor(),
1738 numVariables);
1739 d_cursor += len;
1740 }
1741 else {
1742 invalidate();
1743 }
1744
1745 return *this;
1746}
1747
1748inline
1749ByteInStream& ByteInStream::getArrayInt32(int *variables, int numVariables)
1750{
1751 BSLS_ASSERT_SAFE(variables);
1752 BSLS_ASSERT_SAFE(0 <= numVariables);
1753
1756 return *this; // RETURN
1757 }
1758
1759 const int len = MarshallingUtil::k_SIZEOF_INT32 * numVariables;
1760 if (cursor() + len <= length()) {
1762 d_buffer + cursor(),
1763 numVariables);
1764 d_cursor += len;
1765 }
1766 else {
1767 invalidate();
1768 }
1769
1770 return *this;
1771}
1772
1773inline
1775 int numVariables)
1776{
1777 BSLS_ASSERT_SAFE(variables);
1778 BSLS_ASSERT_SAFE(0 <= numVariables);
1779
1782 return *this; // RETURN
1783 }
1784
1785 const int len = MarshallingUtil::k_SIZEOF_INT32 * numVariables;
1786 if (cursor() + len <= length()) {
1788 d_buffer + cursor(),
1789 numVariables);
1790 d_cursor += len;
1791 }
1792 else {
1793 invalidate();
1794 }
1795
1796 return *this;
1797}
1798
1799inline
1800ByteInStream& ByteInStream::getArrayInt24(int *variables, int numVariables)
1801{
1802 BSLS_ASSERT_SAFE(variables);
1803 BSLS_ASSERT_SAFE(0 <= numVariables);
1804
1807 return *this; // RETURN
1808 }
1809
1810 const int len = MarshallingUtil::k_SIZEOF_INT24 * numVariables;
1811 if (cursor() + len <= length()) {
1813 d_buffer + cursor(),
1814 numVariables);
1815 d_cursor += len;
1816 }
1817 else {
1818 invalidate();
1819 }
1820
1821 return *this;
1822}
1823
1824inline
1826 int numVariables)
1827{
1828 BSLS_ASSERT_SAFE(variables);
1829 BSLS_ASSERT_SAFE(0 <= numVariables);
1830
1833 return *this; // RETURN
1834 }
1835
1836 const int len = MarshallingUtil::k_SIZEOF_INT24 * numVariables;
1837 if (cursor() + len <= length()) {
1839 d_buffer + cursor(),
1840 numVariables);
1841 d_cursor += len;
1842 }
1843 else {
1844 invalidate();
1845 }
1846
1847 return *this;
1848}
1849
1850inline
1851ByteInStream& ByteInStream::getArrayInt16(short *variables, int numVariables)
1852{
1853 BSLS_ASSERT_SAFE(variables);
1854 BSLS_ASSERT_SAFE(0 <= numVariables);
1855
1858 return *this; // RETURN
1859 }
1860
1861 const int len = MarshallingUtil::k_SIZEOF_INT16 * numVariables;
1862 if (cursor() + len <= length()) {
1864 d_buffer + cursor(),
1865 numVariables);
1866 d_cursor += len;
1867 }
1868 else {
1869 invalidate();
1870 }
1871
1872 return *this;
1873}
1874
1875inline
1877 int numVariables)
1878{
1879 BSLS_ASSERT_SAFE(variables);
1880 BSLS_ASSERT_SAFE(0 <= numVariables);
1881
1884 return *this; // RETURN
1885 }
1886
1887 const int len = MarshallingUtil::k_SIZEOF_INT16 * numVariables;
1888 if (cursor() + len <= length()) {
1890 d_buffer + cursor(),
1891 numVariables);
1892 d_cursor += len;
1893 }
1894 else {
1895 invalidate();
1896 }
1897
1898 return *this;
1899}
1900
1901inline
1902ByteInStream& ByteInStream::getArrayInt8(char *variables, int numVariables)
1903{
1904 BSLS_ASSERT_SAFE(variables);
1905 BSLS_ASSERT_SAFE(0 <= numVariables);
1906
1909 return *this; // RETURN
1910 }
1911
1912 const int len = MarshallingUtil::k_SIZEOF_INT8 * numVariables;
1913 if (cursor() + len <= length()) {
1915 d_buffer + cursor(),
1916 numVariables);
1917 d_cursor += len;
1918 }
1919 else {
1920 invalidate();
1921 }
1922
1923 return *this;
1924}
1925
1926inline
1928 int numVariables)
1929{
1930 BSLS_ASSERT_SAFE(variables);
1931 BSLS_ASSERT_SAFE(0 <= numVariables);
1932
1933 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
1934}
1935
1936inline
1937ByteInStream& ByteInStream::getArrayUint8(char *variables, int numVariables)
1938{
1939 BSLS_ASSERT_SAFE(variables);
1940 BSLS_ASSERT_SAFE(0 <= numVariables);
1941
1942 return getArrayInt8(variables, numVariables);
1943}
1944
1945inline
1947 int numVariables)
1948{
1949 BSLS_ASSERT_SAFE(variables);
1950 BSLS_ASSERT_SAFE(0 <= numVariables);
1951
1952 return getArrayInt8(reinterpret_cast<char *>(variables), numVariables);
1953}
1954
1955 // *** arrays of floating-point values ***
1956
1957inline
1959 int numVariables)
1960{
1961 BSLS_ASSERT_SAFE(variables);
1962 BSLS_ASSERT_SAFE(0 <= numVariables);
1963
1966 return *this; // RETURN
1967 }
1968
1969 const int len = MarshallingUtil::k_SIZEOF_FLOAT64 * numVariables;
1970 if (cursor() + len <= length()) {
1972 d_buffer + cursor(),
1973 numVariables);
1974 d_cursor += len;
1975 }
1976 else {
1977 invalidate();
1978 }
1979
1980 return *this;
1981}
1982
1983inline
1984ByteInStream& ByteInStream::getArrayFloat32(float *variables, int numVariables)
1985{
1986 BSLS_ASSERT_SAFE(variables);
1987 BSLS_ASSERT_SAFE(0 <= numVariables);
1988
1991 return *this; // RETURN
1992 }
1993
1994 const int len = MarshallingUtil::k_SIZEOF_FLOAT32 * numVariables;
1995 if (cursor() + len <= length()) {
1997 d_buffer + cursor(),
1998 numVariables);
1999 d_cursor += len;
2000 }
2001 else {
2002 invalidate();
2003 }
2004
2005 return *this;
2006}
2007
2008// ACCESSORS
2009inline
2010ByteInStream::operator const void *() const
2011{
2012 return isValid() ? this : 0;
2013}
2014
2015inline
2016bsl::size_t ByteInStream::cursor() const
2017{
2018 return d_cursor;
2019}
2020
2021inline
2022const char *ByteInStream::data() const
2023{
2024 return d_numBytes ? d_buffer : 0;
2025}
2026
2027inline
2029{
2030 return cursor() == length();
2031}
2032
2033inline
2035{
2036 return d_validFlag;
2037}
2038
2039inline
2040bsl::size_t ByteInStream::length() const
2041{
2042 return d_numBytes;
2043}
2044
2045template <class TYPE>
2046inline
2048{
2049 return InStreamFunctions::bdexStreamIn(stream, value);
2050}
2051
2052} // close package namespace
2053
2054
2055#endif
2056
2057// ----------------------------------------------------------------------------
2058// Copyright 2014 Bloomberg Finance L.P.
2059//
2060// Licensed under the Apache License, Version 2.0 (the "License");
2061// you may not use this file except in compliance with the License.
2062// You may obtain a copy of the License at
2063//
2064// http://www.apache.org/licenses/LICENSE-2.0
2065//
2066// Unless required by applicable law or agreed to in writing, software
2067// distributed under the License is distributed on an "AS IS" BASIS,
2068// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2069// See the License for the specific language governing permissions and
2070// limitations under the License.
2071// ----------------------------- END-OF-FILE ----------------------------------
2072
2073/** @} */
2074/** @} */
2075/** @} */
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 bslstl_stringref.h:374
const CHAR_TYPE * data() const
Definition bslstl_stringref.h:962
size_type length() const
Definition bslstl_stringref.h:984
Definition bslx_byteinstream.h:395
ByteInStream & getArrayInt40(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1697
ByteInStream & getFloat64(double &variable)
Definition bslx_byteinstream.h:1456
ByteInStream & getInt8(char &variable)
Definition bslx_byteinstream.h:1417
ByteInStream & getInt56(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1189
bsl::size_t cursor() const
Return the index of the next byte to be extracted from this stream.
Definition bslx_byteinstream.h:2016
bool isEmpty() const
Definition bslx_byteinstream.h:2028
ByteInStream & getArrayUint16(unsigned short *variables, int numVariables)
Definition bslx_byteinstream.h:1876
bsl::size_t length() const
Definition bslx_byteinstream.h:2040
ByteInStream & getInt40(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1265
ByteInStream & getArrayInt64(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1541
ByteInStream & getUint8(char &variable)
Definition bslx_byteinstream.h:1442
ByteInStream & getUint16(unsigned short &variable)
Definition bslx_byteinstream.h:1398
ByteInStream & getUint48(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1246
ByteInStream & getUint64(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1170
ByteInStream & getUint24(unsigned int &variable)
Definition bslx_byteinstream.h:1360
ByteInStream & getUint40(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1284
ByteInStream & getArrayInt24(int *variables, int numVariables)
Definition bslx_byteinstream.h:1800
ByteInStream & getArrayInt16(short *variables, int numVariables)
Definition bslx_byteinstream.h:1851
ByteInStream & getArrayInt56(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1593
ByteInStream & getLength(int &length)
Definition bslx_byteinstream.h:1069
ByteInStream()
Definition bslx_byteinstream.h:1035
ByteInStream & getInt48(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1227
ByteInStream & getArrayUint24(unsigned int *variables, int numVariables)
Definition bslx_byteinstream.h:1825
void reset()
Definition bslx_byteinstream.h:1122
ByteInStream & getArrayFloat64(double *variables, int numVariables)
Definition bslx_byteinstream.h:1958
ByteInStream & getArrayInt48(bsls::Types::Int64 *variables, int numVariables)
Definition bslx_byteinstream.h:1645
ByteInStream & getArrayUint32(unsigned int *variables, int numVariables)
Definition bslx_byteinstream.h:1774
ByteInStream & getArrayUint56(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1619
ByteInStream & getArrayFloat32(float *variables, int numVariables)
Definition bslx_byteinstream.h:1984
ByteInStream & getArrayUint8(char *variables, int numVariables)
Definition bslx_byteinstream.h:1937
bool isValid() const
Definition bslx_byteinstream.h:2034
ByteInStream & getArrayInt8(char *variables, int numVariables)
Definition bslx_byteinstream.h:1902
friend bsl::ostream & operator<<(bsl::ostream &stream, const ByteInStream &object)
ByteInStream & getInt32(int &variable)
Definition bslx_byteinstream.h:1303
ByteInStream & getArrayInt32(int *variables, int numVariables)
Definition bslx_byteinstream.h:1749
void invalidate()
Definition bslx_byteinstream.h:1116
ByteInStream & getArrayUint64(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1567
ByteInStream & getArrayUint48(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1671
~ByteInStream()
Destroy this object.
Definition bslx_byteinstream.h:1063
ByteInStream & getInt64(bsls::Types::Int64 &variable)
Definition bslx_byteinstream.h:1151
ByteInStream & getFloat32(float &variable)
Definition bslx_byteinstream.h:1475
ByteInStream & getInt16(short &variable)
Definition bslx_byteinstream.h:1379
ByteInStream & getArrayUint40(bsls::Types::Uint64 *variables, int numVariables)
Definition bslx_byteinstream.h:1723
ByteInStream & getString(bsl::string &variable)
Definition bslx_byteinstream.h:1496
ByteInStream & getUint32(unsigned int &variable)
Definition bslx_byteinstream.h:1322
ByteInStream & getUint56(bsls::Types::Uint64 &variable)
Definition bslx_byteinstream.h:1208
ByteInStream & getInt24(int &variable)
Definition bslx_byteinstream.h:1341
ByteInStream & getVersion(int &version)
Definition bslx_byteinstream.h:1101
const char * data() const
Definition bslx_byteinstream.h:2022
#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
bsl::ostream & operator<<(bsl::ostream &stream, const ByteInStream &object)
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
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:1387
static void getInt56(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1168
static void getInt32(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1318
static void getFloat32(float *variable, const char *buffer)
Definition bslx_marshallingutil.h:1508
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:1431
static void getUint64(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1139
static void getInt40(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1270
static void getUint56(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1194
static void getInt64(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1110
static void getArrayInt56(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
@ k_SIZEOF_INT8
Definition bslx_marshallingutil.h:281
@ k_SIZEOF_INT48
Definition bslx_marshallingutil.h:276
@ k_SIZEOF_FLOAT64
Definition bslx_marshallingutil.h:282
@ k_SIZEOF_INT64
Definition bslx_marshallingutil.h:274
@ k_SIZEOF_INT24
Definition bslx_marshallingutil.h:279
@ k_SIZEOF_INT56
Definition bslx_marshallingutil.h:275
@ k_SIZEOF_INT16
Definition bslx_marshallingutil.h:280
@ k_SIZEOF_FLOAT32
Definition bslx_marshallingutil.h:283
@ k_SIZEOF_INT40
Definition bslx_marshallingutil.h:277
@ k_SIZEOF_INT32
Definition bslx_marshallingutil.h:278
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:1570
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:1408
static void getArrayUint32(unsigned int *variables, const char *buffer, int numVariables)
static void getFloat64(double *variable, const char *buffer)
Definition bslx_marshallingutil.h:1482
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:1245
static void getInt24(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1366
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:1294
static void getInt48(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1220
static void getUint32(unsigned int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1342
static void getArrayUint40(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void getInt8(char *variable, const char *buffer)
Definition bslx_marshallingutil.h:1453
static void getArrayUint24(unsigned int *variables, const char *buffer, int numVariables)