BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslx_testinstream.h
Go to the documentation of this file.
1/// @file bslx_testinstream.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslx_testinstream.h -*-C++-*-
8#ifndef INCLUDED_BSLX_TESTINSTREAM
9#define INCLUDED_BSLX_TESTINSTREAM
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslx_testinstream bslx_testinstream
15/// @brief Enable unexternalization of fundamental types with identification.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslx
19/// @{
20/// @addtogroup bslx_testinstream
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslx_testinstream-purpose"> Purpose</a>
25/// * <a href="#bslx_testinstream-classes"> Classes </a>
26/// * <a href="#bslx_testinstream-macros"> Macros </a>
27/// * <a href="#bslx_testinstream-description"> Description </a>
28/// * <a href="#bslx_testinstream-input-limit"> Input Limit </a>
29/// * <a href="#bslx_testinstream-exception-test-macros"> Exception Test Macros </a>
30/// * <a href="#bslx_testinstream-usage"> Usage </a>
31/// * <a href="#bslx_testinstream-example-1-basic-unexternalization-test"> Example 1: Basic Unexternalization Test </a>
32///
33/// # Purpose {#bslx_testinstream-purpose}
34/// Enable unexternalization of fundamental types with identification.
35///
36/// # Classes {#bslx_testinstream-classes}
37///
38/// - bslx::TestInStream: byte-array-based input stream class
39///
40/// # Macros {#bslx_testinstream-macros}
41///
42/// - BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN: macro to begin testing exceptions
43/// - BSLX_TESTINSTREAM_EXCEPTION_TEST_END: macro to end testing exceptions
44///
45/// @see bslx_testoutstream, bslx_byteinstream
46///
47/// # Description {#bslx_testinstream-description}
48/// This component implements a byte-array-based input stream
49/// class, `bslx::TestInStream`, that provides platform-independent input
50/// methods ("unexternalization") on values, and arrays of values, of
51/// fundamental types, and on `bsl::string`. `bslx::TestInStream` also
52/// verifies, for these types, that the type of data requested from the stream
53/// matches what was written to the stream. `bslx::TestInStream` is meant for
54/// testing only.
55///
56/// The `bslx::TestInStream` type reads from a user-supplied buffer directly,
57/// with no data copying or assumption of ownership. The user must therefore
58/// make sure that the lifetime and visibility of the buffer is sufficient to
59/// satisfy the needs of the input stream.
60///
61/// This component is intended to be used in conjunction with the
62/// @ref bslx_testoutstream externalization component. Each input method of
63/// `bslx::TestInStream` reads either a value or a homogeneous array of values
64/// of a fundamental type, in a format that was written by the corresponding
65/// `bslx::TestOutStream` method. In general, the user of this component cannot
66/// rely on being able to read data that was written by any mechanism other than
67/// `bslx::TestOutStream`.
68///
69/// The supported types and required content are listed in the `bslx`
70/// package-level documentation under "Supported Types".
71///
72/// Note that input streams can be *invalidated* explicitly and queried for
73/// *validity* and *emptiness*. Reading from an initially invalid stream has no
74/// effect. Attempting to read beyond the end of a stream will automatically
75/// invalidate the stream. Whenever an inconsistent value is detected, the
76/// stream should be invalidated explicitly.
77///
78/// ## Input Limit {#bslx_testinstream-input-limit}
79///
80///
81/// If exceptions are enabled at compile time, the test input stream can be
82/// configured to throw an exception after a specified number of input requests
83/// is exceeded. If the input limit is less than zero (default), then the
84/// stream never throws an exception. Note that a non-negative input limit is
85/// decremented after each input attempt, and throws only when the current input
86/// limit transitions from 0 to -1; no additional exceptions will be thrown
87/// until the input limit is again reset to a non-negative value.
88///
89/// The input limit is set using the `setInputLimit` manipulator.
90///
91/// ## Exception Test Macros {#bslx_testinstream-exception-test-macros}
92///
93///
94/// This component also provides a pair of macros:
95///
96/// * `BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN(testInStream)`
97/// * `BSLX_TESTINSTREAM_EXCEPTION_TEST_END`
98///
99/// These macros can be used for testing exception-safety of classes and their
100/// methods when BDEX streaming is involved. A reference to an object of type
101/// `bslx::TestInStream` must be supplied as an argument to the `*_BEGIN` macro.
102/// Note that if exception-handling is disabled (i.e., if
103/// `-DBDE_BUILD_TARGET_EXC` was *not* supplied at compile time), then the
104/// macros simply print the following:
105/// @code
106/// BSLX EXCEPTION TEST -- (NOT ENABLED) --
107/// @endcode
108/// When exception-handling is enabled (i.e., if `-DBDE_BUILD_TARGET_EXC` was
109/// supplied at compile time), the `*_BEGIN` macro will set the input limit of
110/// the supplied instream to 0, `try` the code being tested, `catch` any
111/// `TestInstreamException`s that are thrown, and keep increasing the input
112/// limit until the code being tested completes successfully.
113///
114/// ## Usage {#bslx_testinstream-usage}
115///
116///
117/// This section illustrates intended use of this component.
118///
119/// ### Example 1: Basic Unexternalization Test {#bslx_testinstream-example-1-basic-unexternalization-test}
120///
121///
122/// Suppose we wish to implement a (deliberately simple) `MyPerson` class as a
123/// value-semantic object that supports BDEX externalization and
124/// unexternalization. In addition to whatever data and methods that we choose
125/// to put into our design, we must supply three methods having specific names
126/// and signatures in order to comply with the BDEX protocol: a class method
127/// `maxSupportedBdexVersion`, an accessor (i.e., a `const` method)
128/// `bdexStreamOut`, and a manipulator (i.e., a non-`const` method)
129/// `bdexStreamIn`. This example shows how to implement those three methods.
130///
131/// In this example we will not worry overly about "good design" of the
132/// `MyPerson` component, and we will declare but not implement illustrative
133/// methods and free operators, except for the three required BDEX methods,
134/// which are implemented in full. In particular, we will not make explicit use
135/// of `bslma` allocators; a more complete design would do so:
136///
137/// First, we implement `MyPerson`:
138/// @code
139/// class MyPerson {
140/// bsl::string d_firstName;
141/// bsl::string d_lastName;
142/// int d_age;
143///
144/// friend bool operator==(const MyPerson&, const MyPerson&);
145///
146/// public:
147/// // CLASS METHODS
148///
149/// /// Return the maximum valid BDEX format version, as indicated by
150/// /// the specified `versionSelector`, to be passed to the
151/// /// `bdexStreamOut` method. Note that it is highly recommended that
152/// /// `versionSelector` be formatted as "YYYYMMDD", a date
153/// /// representation. Also note that `versionSelector` should be a
154/// /// *compile*-time-chosen value that selects a format version
155/// /// supported by both externalizer and unexternalizer. See the
156/// /// `bslx` package-level documentation for more information on BDEX
157/// /// streaming of value-semantic types and containers.
158/// static int maxSupportedBdexVersion(int versionSelector);
159///
160/// // CREATORS
161///
162/// /// Create a default person.
163/// MyPerson();
164///
165/// /// Create a person having the specified `firstName`, `lastName`,
166/// /// and `age`.
167/// MyPerson(const char *firstName, const char *lastName, int age);
168///
169/// /// Create a person having the value of the specified `original` person.
170/// MyPerson(const MyPerson& original);
171///
172/// /// Destroy this object.
173/// ~MyPerson();
174///
175/// // MANIPULATORS
176///
177/// /// Assign to this person the value of the specified `rhs` person, and
178/// /// return a reference to this person.
179/// MyPerson& operator=(const MyPerson& rhs);
180///
181/// /// Assign to this object the value read from the specified input
182/// /// `stream` using the specified `version` format, and return a
183/// /// reference to `stream`. If `stream` is initially invalid, this
184/// /// operation has no effect. If `version` is not supported, this
185/// /// object is unaltered and `stream` is invalidated, but otherwise
186/// /// unmodified. If `version` is supported but `stream` becomes
187/// /// invalid during this operation, this object has an undefined, but
188/// /// valid, state. Note that no version is read from `stream`. See
189/// /// the `bslx` package-level documentation for more information on
190/// /// BDEX streaming of value-semantic types and containers.
191/// template <class STREAM>
192/// STREAM& bdexStreamIn(STREAM& stream, int version);
193///
194/// //...
195///
196/// // ACCESSORS
197///
198/// /// Return the first name of this person.
199/// const bsl::string& firstName() const;
200///
201/// /// Return the last name of this person.
202/// const bsl::string& lastName() const;
203///
204/// /// Return the age of this person.
205/// int age() const;
206///
207/// /// Write the value of this object, using the specified `version`
208/// /// format, to the specified output `stream`, and return a reference
209/// /// to `stream`. If `stream` is initially invalid, this operation
210/// /// has no effect. If `version` is not supported, `stream` is
211/// /// invalidated, but otherwise unmodified. Note that `version` is
212/// /// not written to `stream`. See the `bslx` package-level
213/// /// documentation for more information on BDEX streaming of
214/// /// value-semantic types and containers.
215/// template <class STREAM>
216/// STREAM& bdexStreamOut(STREAM& stream, int version) const;
217///
218/// //...
219///
220/// };
221///
222/// // FREE OPERATORS
223///
224/// /// Return `true` if the specified `lhs` and `rhs` person objects have
225/// /// the same value, and `false` otherwise. Two person objects have the
226/// /// same value if they have the same first name, last name, and age.
227/// bool operator==(const MyPerson& lhs, const MyPerson& rhs);
228///
229/// /// Return `true` if the specified `lhs` and `rhs` person objects do not
230/// /// have the same value, and `false` otherwise. Two person objects
231/// /// differ in value if they differ in first name, last name, or age.
232/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs);
233///
234/// /// Write the specified `person` value to the specified output `stream`
235/// /// in some reasonable format, and return a reference to `stream`.
236/// bsl::ostream& operator<<(bsl::ostream& stream, const MyPerson& person);
237///
238/// // ========================================================================
239/// // INLINE FUNCTION DEFINITIONS
240/// // ========================================================================
241///
242/// // CLASS METHODS
243/// inline
244/// int MyPerson::maxSupportedBdexVersion(int /* versionSelector */) {
245/// return 1;
246/// }
247///
248/// // CREATORS
249/// inline
250/// MyPerson::MyPerson()
251/// : d_firstName("")
252/// , d_lastName("")
253/// , d_age(0)
254/// {
255/// }
256///
257/// inline
258/// MyPerson::MyPerson(const char *firstName, const char *lastName, int age)
259/// : d_firstName(firstName)
260/// , d_lastName(lastName)
261/// , d_age(age)
262/// {
263/// }
264///
265/// inline
266/// MyPerson::~MyPerson()
267/// {
268/// }
269///
270/// template <class STREAM>
271/// STREAM& MyPerson::bdexStreamIn(STREAM& stream, int version)
272/// {
273/// if (stream) {
274/// switch (version) { // switch on the 'bslx' version
275/// case 1: {
276/// stream.getString(d_firstName);
277/// if (!stream) {
278/// d_firstName = "stream error"; // *might* be corrupted;
279/// // value for testing
280/// return stream;
281/// }
282/// stream.getString(d_lastName);
283/// if (!stream) {
284/// d_lastName = "stream error"; // *might* be corrupted;
285/// // value for testing
286/// return stream;
287/// }
288/// stream.getInt32(d_age);
289/// if (!stream) {
290/// d_age = 999; // *might* be corrupted; value for testing
291/// return stream;
292/// }
293/// } break;
294/// default: {
295/// stream.invalidate();
296/// }
297/// }
298/// }
299/// return stream;
300/// }
301///
302/// // ACCESSORS
303/// template <class STREAM>
304/// STREAM& MyPerson::bdexStreamOut(STREAM& stream, int version) const
305/// {
306/// switch (version) {
307/// case 1: {
308/// stream.putString(d_firstName);
309/// stream.putString(d_lastName);
310/// stream.putInt32(d_age);
311/// } break;
312/// default: {
313/// stream.invalidate();
314/// } break;
315/// }
316/// return stream;
317/// }
318/// @endcode
319/// Then, we can exercise the new `MyPerson` value-semantic class by
320/// externalizing and reconstituting an object. First, create a `MyPerson`
321/// `janeSmith` and a `bslx::TestOutStream` `outStream`:
322/// @code
323/// MyPerson janeSmith("Jane", "Smith", 42);
324/// bslx::TestOutStream outStream(20131127);
325/// const int VERSION = 1;
326/// outStream.putVersion(VERSION);
327/// janeSmith.bdexStreamOut(outStream, VERSION);
328/// assert(outStream.isValid());
329/// @endcode
330/// Next, create a `MyPerson` `janeCopy` initialized to the default value, and
331/// assert that `janeCopy` is different from `janeSmith`:
332/// @code
333/// MyPerson janeCopy;
334/// assert(janeCopy != janeSmith);
335/// @endcode
336/// Then, create a `bslx::TestInStream` `inStream` initialized with the buffer
337/// from the `bslx::TestOutStream` object `outStream` and unexternalize this
338/// data into `janeCopy`:
339/// @code
340/// bslx::TestInStream inStream(outStream.data(), outStream.length());
341/// int version;
342/// inStream.getVersion(version);
343/// janeCopy.bdexStreamIn(inStream, version);
344/// assert(inStream.isValid());
345/// @endcode
346/// Finally, `assert` the obtained values are as expected and display the
347/// results to `bsl::stdout`:
348/// @code
349/// assert(version == VERSION);
350/// assert(janeCopy == janeSmith);
351///
352/// if (janeCopy == janeSmith) {
353/// bsl::cout << "Successfully serialized and de-serialized Jane Smith:"
354/// << "\n\tFirstName: " << janeCopy.firstName()
355/// << "\n\tLastName : " << janeCopy.lastName()
356/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
357/// }
358/// else {
359/// bsl::cout << "Serialization unsuccessful. 'janeCopy' holds:"
360/// << "\n\tFirstName: " << janeCopy.firstName()
361/// << "\n\tLastName : " << janeCopy.lastName()
362/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
363/// }
364/// @endcode
365/// @}
366/** @} */
367/** @} */
368
369/** @addtogroup bsl
370 * @{
371 */
372/** @addtogroup bslx
373 * @{
374 */
375/** @addtogroup bslx_testinstream
376 * @{
377 */
378
379#include <bslscm_version.h>
380
383#include <bslx_typecode.h>
384
385#include <bsls_assert.h>
386#include <bsls_buildtarget.h>
387#include <bsls_keyword.h>
388#include <bsls_types.h>
389
390#include <bsl_cstddef.h>
391#include <bsl_iosfwd.h>
392#include <bsl_string.h>
393#include <bsl_vector.h>
394
395
396namespace bslx {
397
398 // ==================
399 // class TestInStream
400 // ==================
401
402/// This class provides input methods to unexternalize values, and C-style
403/// arrays of values, of fundamental types from their byte representations.
404/// Each input method also verifies the input value type. By default, if
405/// invalid data is detected, error messages are displayed on `stdout`; this
406/// error reporting may be disabled via the `setQuiet` method.
407///
408/// \note Note that attempting to read beyond the end of a stream will automatically
409/// invalidate the stream. See the `bslx` package-level documentation for
410/// the definition of the BDEX `InStream` protocol.
411///
412/// See @ref bslx_testinstream
414
415 // DATA
416 const char *d_buffer; // bytes to be unexternalized
417
418 bsl::size_t d_numBytes; // number of bytes in 'd_buffer'
419
420 bool d_validFlag; // stream validity flag; 'true' if stream is in
421 // valid state, 'false' otherwise
422
423 int d_quietFlag; // flag for "quiet" mode
424
425 int d_inputLimit; // number of input op's before exception
426
427 bsl::size_t d_cursor; // index of the next byte to be extracted from
428 // this stream
429
430 // FRIENDS
431 friend bsl::ostream& operator<<(bsl::ostream&, const TestInStream&);
432
433 private:
434 // NOT IMPLEMENTED
436 TestInStream& operator=(const TestInStream&);
437
438 private:
439 // PRIVATE MANIPULATORS
440
441 /// Verify the validity of the type code and array length, and the
442 /// sufficiency of data at the current cursor position in the external
443 /// memory buffer. Extract the type code at the cursor position from the
444 /// buffer. If the type code does not correspond to the specified `code`,
445 /// then mark this stream as invalid, and if the quiet flag is zero print
446 /// an error message. Otherwise, advance the cursor by the size of the
447 /// type code and extract the array length. If the length does not
448 /// correspond to the specified `numElements`, then mark this stream as
449 /// invalid, and if the quiet flag is zero print an error message.
450 /// Otherwise, advance the cursor by the size of the array length, and
451 /// verify that the buffer contains sufficient bytes for `numElements` of
452 /// the specified `elementSize`. If there are too few bytes in the buffer,
453 /// then mark this stream as invalid. If this stream is invalid on entry, this function has no effect.
454 ///
455 /// \pre The behavior is undefined unless `0 < elementSize` and `0 <= numElements`.
456 ///
457 /// \note Note that error messages are
458 /// not printed for insufficient data in the buffer.
459 void checkArray(TypeCode::Enum code,
460 int elementSize,
461 int numElements);
462
463 /// Verify the validity of the type code and the sufficiency of data at the
464 /// current cursor position in the external memory buffer. Extract the
465 /// type code at the cursor position from the buffer. If the type code
466 /// does not correspond to the specified `code`, then mark this stream as
467 /// invalid and, if the quiet flag is zero, print an error message.
468 /// Otherwise, advance the cursor position by the size of the type code,
469 /// and verify that the buffer contains sufficient bytes for the specified
470 /// `numExpectedBytes`. If there are too few bytes, then this stream is
471 /// marked as invalid. If this stream is invalid on entry, this function has no effect.
472 ///
473 /// \pre The behavior is undefined unless
474 /// `0 < numExpectedBytes`. Also note that error messages are not printed
475 /// for insufficient data in the buffer.
476 void checkTypeCodeAndAvailableLength(TypeCode::Enum code,
477 bsl::size_t numExpectedBytes);
478
479 /// Decrement the internal input limit of this test stream. If the input
480 /// limit becomes negative and exception-handling is enabled (enabled by
481 /// default), then throw a `TestInStreamException` object initialized with
482 /// the specified type `code`. If exception-handling is not enabled, this
483 /// method has no effect.
484 void throwExceptionIfInputLimitExhausted(const TypeCode::Enum& code);
485
486 public:
487 // CREATORS
488
489 /// Create an empty test input stream.
490 /// \note Note that the constructed object is
491 /// useless until a buffer is set with the `reset` method.
492 explicit TestInStream();
493
494 /// Create a test input stream containing the specified initial `numBytes` from the specified `buffer`.
495 ///
496 /// \pre The behavior is undefined unless
497 /// `0 == numBytes` if `0 == buffer`.
498 TestInStream(const char *buffer, bsl::size_t numBytes);
499
500 /// Create a test input stream containing the specified `srcData`.
501 explicit TestInStream(const bslstl::StringRef& srcData);
502
503 /// Destroy this test input stream.
505
506 // MANIPULATORS
507
508 /// If required, throw a `TestInStreamException` (see
509 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
510 /// unsigned integer type code, verify the type of the next value in this
511 /// stream, consume that 8-bit unsigned integer or 32-bit signed integer
512 /// value representing a length (see the `bslx` package-level
513 /// documentation) into the specified `variable` if its type is
514 /// appropriate, update the cursor location, and return a reference to this
515 /// stream. Consume an 8-bit unsigned integer if the most significant bit
516 /// of this byte is 0, otherwise consume a 32-bit signed integer and set
517 /// the most significant bit to zero in the resultant `variable`. If the
518 /// type is incorrect, then this stream is marked invalid and the value of
519 /// `variable` is unchanged. If this stream is initially invalid, this
520 /// operation has no effect. If this function otherwise fails to extract a
521 /// valid value, this stream is marked invalid and the value of `variable`
522 /// is undefined.
523 TestInStream& getLength(int& variable);
524
525 /// If required, throw a `TestInStreamException` (see
526 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
527 /// unsigned integer type code, verify the type of the next value in this
528 /// stream, consume that 8-bit unsigned integer value representing a
529 /// version (see the `bslx` package-level documentation) into the specified
530 /// `variable` if its type is appropriate, update the cursor location, and
531 /// return a reference to this stream. If the type is incorrect, then this
532 /// stream is marked invalid and the value of `variable` is unchanged. If
533 /// this stream is initially invalid, this operation has no effect. If
534 /// this function otherwise fails to extract a valid value, this stream is
535 /// marked invalid and the value of `variable` is undefined.
536 TestInStream& getVersion(int& variable);
537
538 /// Put this input stream in an invalid state. This function has no effect if this stream is already invalid.
539 ///
540 /// \note Note that this function should be
541 /// called whenever a value extracted from this stream is determined to be
542 /// invalid, inconsistent, or otherwise incorrect.
543 void invalidate();
544
545 /// Set the index of the next byte to be extracted from this stream to 0
546 /// (i.e., the beginning of the stream) and validate this stream if it is
547 /// currently invalid.
548 void reset();
549
550 /// Reset this stream to extract from the specified `buffer` containing the
551 /// specified `numBytes`, set the index of the next byte to be extracted to
552 /// 0 (i.e., the beginning of the stream), and validate this stream if it is currently invalid.
553 ///
554 /// \pre The behavior is undefined unless `0 == numBytes`
555 /// if `0 == buffer`.
556 void reset(const char *buffer, bsl::size_t numBytes);
557
558 /// Reset this stream to extract from the specified `srcData`, set the
559 /// index of the next byte to be extracted to 0 (i.e., the beginning of the
560 /// stream), and validate this stream if it is currently invalid.
561 void reset(const bslstl::StringRef& srcData);
562
563 /// Set the index of the next byte to be extracted from this stream to the
564 /// specified `offset` from the beginning of the stream, and validate this stream if it is currently invalid.
565 ///
566 /// \pre The behavior is undefined unless
567 /// `offset <= length()`.
568 void seek(bsl::size_t offset);
569
570 /// Set the number of input operations allowed on this stream to the
571 /// specified `limit` before an exception is thrown. If `limit` is less
572 /// than 0, no exception is to be thrown. By default, no exception is
573 /// scheduled.
574 void setInputLimit(int limit);
575
576 /// Set the quiet mode for this test stream to the specified (boolean)
577 /// `flagValue`. If `flagValue` is `true`, then quiet mode is turned ON
578 /// and no error messages will be written to standard output. If `flagValue` is `false`, then quiet mode is turned OFF.
579 ///
580 /// \note Note that quiet
581 /// mode is turned OFF by default.
582 void setQuiet(bool flagValue);
583
584 // *** scalar integer values ***
585
586 /// If required, throw a `TestInStreamException` (see
587 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
588 /// unsigned integer type code, verify the type of the next value in this
589 /// stream, consume that 64-bit signed integer value into the specified
590 /// `variable` if its type is appropriate, update the cursor location, and
591 /// return a reference to this stream. If the type is incorrect, then this
592 /// stream is marked invalid and the value of `variable` is unchanged. If
593 /// this stream is initially invalid, this operation has no effect. If
594 /// this function otherwise fails to extract a valid value, this stream is
595 /// marked invalid and the value of `variable` is undefined.
597
598 /// If required, throw a `TestInStreamException` (see
599 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
600 /// unsigned integer type code, verify the type of the next value in this
601 /// stream, consume that 64-bit unsigned integer value into the specified
602 /// `variable` if its type is appropriate, update the cursor location, and
603 /// return a reference to this stream. If the type is incorrect, then this
604 /// stream is marked invalid and the value of `variable` is unchanged. If
605 /// this stream is initially invalid, this operation has no effect. If
606 /// this function otherwise fails to extract a valid value, this stream is
607 /// marked invalid and the value of `variable` is undefined.
609
610 /// If required, throw a `TestInStreamException` (see
611 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
612 /// unsigned integer type code, verify the type of the next value in this
613 /// stream, consume that 56-bit signed integer value into the specified
614 /// `variable` if its type is appropriate, update the cursor location, and
615 /// return a reference to this stream. If the type is incorrect, then this
616 /// stream is marked invalid and the value of `variable` is unchanged. If
617 /// this stream is initially invalid, this operation has no effect. If
618 /// this function otherwise fails to extract a valid value, this stream is
619 /// marked invalid and the value of `variable` is undefined.
621
622 /// If required, throw a `TestInStreamException` (see
623 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
624 /// unsigned integer type code, verify the type of the next value in this
625 /// stream, consume that 56-bit unsigned integer value into the specified
626 /// `variable` if its type is appropriate, update the cursor location, and
627 /// return a reference to this stream. If the type is incorrect, then this
628 /// stream is marked invalid and the value of `variable` is unchanged. If
629 /// this stream is initially invalid, this operation has no effect. If
630 /// this function otherwise fails to extract a valid value, this stream is
631 /// marked invalid and the value of `variable` is undefined.
633
634 /// If required, throw a `TestInStreamException` (see
635 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
636 /// unsigned integer type code, verify the type of the next value in this
637 /// stream, consume that 48-bit signed integer value into the specified
638 /// `variable` if its type is appropriate, update the cursor location, and
639 /// return a reference to this stream. If the type is incorrect, then this
640 /// stream is marked invalid and the value of `variable` is unchanged. If
641 /// this stream is initially invalid, this operation has no effect. If
642 /// this function otherwise fails to extract a valid value, this stream is
643 /// marked invalid and the value of `variable` is undefined.
645
646 /// If required, throw a `TestInStreamException` (see
647 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
648 /// unsigned integer type code, verify the type of the next value in this
649 /// stream, consume that 48-bit unsigned integer value into the specified
650 /// `variable` if its type is appropriate, update the cursor location, and
651 /// return a reference to this stream. If the type is incorrect, then this
652 /// stream is marked invalid and the value of `variable` is unchanged. If
653 /// this stream is initially invalid, this operation has no effect. If
654 /// this function otherwise fails to extract a valid value, this stream is
655 /// marked invalid and the value of `variable` is undefined.
657
658 /// If required, throw a `TestInStreamException` (see
659 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
660 /// unsigned integer type code, verify the type of the next value in this
661 /// stream, consume that 40-bit signed integer value into the specified
662 /// `variable` if its type is appropriate, update the cursor location, and
663 /// return a reference to this stream. If the type is incorrect, then this
664 /// stream is marked invalid and the value of `variable` is unchanged. If
665 /// this stream is initially invalid, this operation has no effect. If
666 /// this function otherwise fails to extract a valid value, this stream is
667 /// marked invalid and the value of `variable` is undefined.
669
670 /// If required, throw a `TestInStreamException` (see
671 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
672 /// unsigned integer type code, verify the type of the next value in this
673 /// stream, consume that 40-bit unsigned integer value into the specified
674 /// `variable` if its type is appropriate, update the cursor location, and
675 /// return a reference to this stream. If the type is incorrect, then this
676 /// stream is marked invalid and the value of `variable` is unchanged. If
677 /// this stream is initially invalid, this operation has no effect. If
678 /// this function otherwise fails to extract a valid value, this stream is
679 /// marked invalid and the value of `variable` is undefined.
681
682 /// If required, throw a `TestInStreamException` (see
683 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
684 /// unsigned integer type code, verify the type of the next value in this
685 /// stream, consume that 32-bit signed integer value into the specified
686 /// `variable` if its type is appropriate, update the cursor location, and
687 /// return a reference to this stream. If the type is incorrect, then this
688 /// stream is marked invalid and the value of `variable` is unchanged. If
689 /// this stream is initially invalid, this operation has no effect. If
690 /// this function otherwise fails to extract a valid value, this stream is
691 /// marked invalid and the value of `variable` is undefined.
692 TestInStream& getInt32(int& variable);
693
694 /// If required, throw a `TestInStreamException` (see
695 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
696 /// unsigned integer type code, verify the type of the next value in this
697 /// stream, consume that 32-bit unsigned integer value into the specified
698 /// `variable` if its type is appropriate, update the cursor location, and
699 /// return a reference to this stream. If the type is incorrect, then this
700 /// stream is marked invalid and the value of `variable` is unchanged. If
701 /// this stream is initially invalid, this operation has no effect. If
702 /// this function otherwise fails to extract a valid value, this stream is
703 /// marked invalid and the value of `variable` is undefined.
704 TestInStream& getUint32(unsigned int& variable);
705
706 /// If required, throw a `TestInStreamException` (see
707 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
708 /// unsigned integer type code, verify the type of the next value in this
709 /// stream, consume that 24-bit signed integer value into the specified
710 /// `variable` if its type is appropriate, update the cursor location, and
711 /// return a reference to this stream. If the type is incorrect, then this
712 /// stream is marked invalid and the value of `variable` is unchanged. If
713 /// this stream is initially invalid, this operation has no effect. If
714 /// this function otherwise fails to extract a valid value, this stream is
715 /// marked invalid and the value of `variable` is undefined.
716 TestInStream& getInt24(int& variable);
717
718 /// If required, throw a `TestInStreamException` (see
719 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
720 /// unsigned integer type code, verify the type of the next value in this
721 /// stream, consume that 24-bit unsigned integer value into the specified
722 /// `variable` if its type is appropriate, update the cursor location, and
723 /// return a reference to this stream. If the type is incorrect, then this
724 /// stream is marked invalid and the value of `variable` is unchanged. If
725 /// this stream is initially invalid, this operation has no effect. If
726 /// this function otherwise fails to extract a valid value, this stream is
727 /// marked invalid and the value of `variable` is undefined.
728 TestInStream& getUint24(unsigned int& variable);
729
730 /// If required, throw a `TestInStreamException` (see
731 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
732 /// unsigned integer type code, verify the type of the next value in this
733 /// stream, consume that 16-bit signed integer value into the specified
734 /// `variable` if its type is appropriate, update the cursor location, and
735 /// return a reference to this stream. If the type is incorrect, then this
736 /// stream is marked invalid and the value of `variable` is unchanged. If
737 /// this stream is initially invalid, this operation has no effect. If
738 /// this function otherwise fails to extract a valid value, this stream is
739 /// marked invalid and the value of `variable` is undefined.
740 TestInStream& getInt16(short& variable);
741
742 /// If required, throw a `TestInStreamException` (see
743 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
744 /// unsigned integer type code, verify the type of the next value in this
745 /// stream, consume that 16-bit unsigned integer value into the specified
746 /// `variable` if its type is appropriate, update the cursor location, and
747 /// return a reference to this stream. If the type is incorrect, then this
748 /// stream is marked invalid and the value of `variable` is unchanged. If
749 /// this stream is initially invalid, this operation has no effect. If
750 /// this function otherwise fails to extract a valid value, this stream is
751 /// marked invalid and the value of `variable` is undefined.
752 TestInStream& getUint16(unsigned short& variable);
753
754 /// If required, throw a `TestInStreamException` (see
755 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
756 /// unsigned integer type code, verify the type of the next value in this
757 /// stream, consume that 8-bit signed integer value into the specified
758 /// `variable` if its type is appropriate, update the cursor location, and
759 /// return a reference to this stream. If the type is incorrect, then this
760 /// stream is marked invalid and the value of `variable` is unchanged. If
761 /// this stream is initially invalid, this operation has no effect. If
762 /// this function otherwise fails to extract a valid value, this stream is
763 /// marked invalid and the value of `variable` is undefined.
764 TestInStream& getInt8(char& variable);
765 TestInStream& getInt8(signed char& variable);
766
767 /// If required, throw a `TestInStreamException` (see
768 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
769 /// unsigned integer type code, verify the type of the next value in this
770 /// stream, consume that 8-bit unsigned integer value into the specified
771 /// `variable` if its type is appropriate, update the cursor location, and
772 /// return a reference to this stream. If the type is incorrect, then this
773 /// stream is marked invalid and the value of `variable` is unchanged. If
774 /// this stream is initially invalid, this operation has no effect. If
775 /// this function otherwise fails to extract a valid value, this stream is
776 /// marked invalid and the value of `variable` is undefined.
777 TestInStream& getUint8(char& variable);
778 TestInStream& getUint8(unsigned char& variable);
779
780 // *** scalar floating-point values ***
781
782 /// If required, throw a `TestInStreamException` (see
783 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
784 /// unsigned integer type code, verify the type of the next value in
785 /// this stream, consume that IEEE double-precision (8-byte)
786 /// floating-point value into the specified `variable` if its type is
787 /// appropriate, update the cursor location, and return a reference to
788 /// this stream. If the type is incorrect, then this stream is marked
789 /// invalid and the value of `variable` is unchanged. If this stream is
790 /// initially invalid, this operation has no effect. If this function
791 /// otherwise fails to extract a valid value, this stream is marked invalid and the value of `variable` is undefined.
792 ///
793 /// \note Note that for
794 /// non-conforming platforms, this operation may be lossy.
795 TestInStream& getFloat64(double& variable);
796
797 /// If required, throw a `TestInStreamException` (see
798 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
799 /// unsigned integer type code, verify the type of the next value in
800 /// this stream, consume that IEEE single-precision (4-byte)
801 /// floating-point value into the specified `variable` if its type is
802 /// appropriate, update the cursor location, and return a reference to
803 /// this stream. If the type is incorrect, then this stream is marked
804 /// invalid and the value of `variable` is unchanged. If this stream is
805 /// initially invalid, this operation has no effect. If this function
806 /// otherwise fails to extract a valid value, this stream is marked invalid and the value of `variable` is undefined.
807 ///
808 /// \note Note that for
809 /// non-conforming platforms, this operation may be lossy.
810 TestInStream& getFloat32(float& variable);
811
812 // *** string values ***
813
814 /// If required, throw a `TestInStreamException` (see
815 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume a string
816 /// from this input stream, assign that value to the specified
817 /// `variable`, update the cursor location, and return a reference to
818 /// this stream. If this stream is initially invalid, this operation
819 /// has no effect. If this function otherwise fails to extract a valid
820 /// value, this stream is marked invalid and the value of `variable` is
821 /// undefined. The string must be prefaced by a non-negative integer
822 /// indicating the number of characters composing the string.
823 ///
824 /// \pre The behavior is undefined unless the length indicator is non-negative.
826
827 // *** arrays of integer values ***
828
829 /// If required, throw a `TestInStreamException` (see
830 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
831 /// unsigned integer type code, verify the type of the next value in
832 /// this stream, consume that 64-bit signed integer array value into the
833 /// specified `variables` of the specified `numVariables` if its type
834 /// and length are appropriate, update the cursor location, and return a
835 /// reference to this stream. If the type is incorrect, then this
836 /// stream is marked invalid and the value of `variables` is unchanged.
837 /// If this stream is initially invalid, this operation has no effect.
838 /// If this function otherwise fails to extract a valid value, this
839 /// stream is marked invalid and the value of `variables` is undefined.
840 ///
841 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
842 /// has sufficient capacity.
844 int numVariables);
845
846 /// If required, throw a `TestInStreamException` (see
847 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
848 /// unsigned integer type code, verify the type of the next value in
849 /// this stream, consume that 64-bit unsigned integer array value into
850 /// the specified `variables` of the specified `numVariables` if its
851 /// type and length are appropriate, update the cursor location, and
852 /// return a reference to this stream. If the type is incorrect, then
853 /// this stream is marked invalid and the value of `variables` is
854 /// unchanged. If this stream is initially invalid, this operation has
855 /// no effect. If this function otherwise fails to extract a valid
856 /// value, this stream is marked invalid and the value of `variables` is undefined.
857 ///
858 /// \pre The behavior is undefined unless `0 <= numVariables` and
859 /// `variables` has sufficient capacity.
861 int numVariables);
862
863 /// If required, throw a `TestInStreamException` (see
864 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
865 /// unsigned integer type code, verify the type of the next value in
866 /// this stream, consume that 56-bit signed integer array value into the
867 /// specified `variables` of the specified `numVariables` if its type
868 /// and length are appropriate, update the cursor location, and return a
869 /// reference to this stream. If the type is incorrect, then this
870 /// stream is marked invalid and the value of `variables` is unchanged.
871 /// If this stream is initially invalid, this operation has no effect.
872 /// If this function otherwise fails to extract a valid value, this
873 /// stream is marked invalid and the value of `variables` is undefined.
874 ///
875 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
876 /// has sufficient capacity.
878 int numVariables);
879
880 /// If required, throw a `TestInStreamException` (see
881 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
882 /// unsigned integer type code, verify the type of the next value in
883 /// this stream, consume that 56-bit unsigned integer array value into
884 /// the specified `variables` of the specified `numVariables` if its
885 /// type and length are appropriate, update the cursor location, and
886 /// return a reference to this stream. If the type is incorrect, then
887 /// this stream is marked invalid and the value of `variables` is
888 /// unchanged. If this stream is initially invalid, this operation has
889 /// no effect. If this function otherwise fails to extract a valid
890 /// value, this stream is marked invalid and the value of `variables` is undefined.
891 ///
892 /// \pre The behavior is undefined unless `0 <= numVariables` and
893 /// `variables` has sufficient capacity.
895 int numVariables);
896
897 /// If required, throw a `TestInStreamException` (see
898 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
899 /// unsigned integer type code, verify the type of the next value in
900 /// this stream, consume that 48-bit signed integer array value into the
901 /// specified `variables` of the specified `numVariables` if its type
902 /// and length are appropriate, update the cursor location, and return a
903 /// reference to this stream. If the type is incorrect, then this
904 /// stream is marked invalid and the value of `variables` is unchanged.
905 /// If this stream is initially invalid, this operation has no effect.
906 /// If this function otherwise fails to extract a valid value, this
907 /// stream is marked invalid and the value of `variables` is undefined.
908 ///
909 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
910 /// has sufficient capacity.
912 int numVariables);
913
914 /// If required, throw a `TestInStreamException` (see
915 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
916 /// unsigned integer type code, verify the type of the next value in
917 /// this stream, consume that 48-bit unsigned integer array value into
918 /// the specified `variables` of the specified `numVariables` if its
919 /// type and length are appropriate, update the cursor location, and
920 /// return a reference to this stream. If the type is incorrect, then
921 /// this stream is marked invalid and the value of `variables` is
922 /// unchanged. If this stream is initially invalid, this operation has
923 /// 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
927 /// `variables` has sufficient capacity.
929 int numVariables);
930
931 /// If required, throw a `TestInStreamException` (see
932 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
933 /// unsigned integer type code, verify the type of the next value in
934 /// this stream, consume that 40-bit signed integer array value into the
935 /// specified `variables` of the specified `numVariables` if its type
936 /// and length are appropriate, update the cursor location, and return a
937 /// reference to this stream. If the type is incorrect, then this
938 /// stream is marked invalid and the value of `variables` is unchanged.
939 /// If this stream is initially invalid, this operation has no effect.
940 /// If this function otherwise fails to extract a valid value, this
941 /// stream is marked invalid and the value of `variables` is undefined.
942 ///
943 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
944 /// has sufficient capacity.
946 int numVariables);
947
948 /// If required, throw a `TestInStreamException` (see
949 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
950 /// unsigned integer type code, verify the type of the next value in
951 /// this stream, consume that 40-bit unsigned integer array value into
952 /// the specified `variables` of the specified `numVariables` if its
953 /// type and length are appropriate, update the cursor location, and
954 /// return a reference to this stream. If the type is incorrect, then
955 /// this stream is marked invalid and the value of `variables` is
956 /// unchanged. If this stream is initially invalid, this operation has
957 /// no effect. If this function otherwise fails to extract a valid
958 /// value, this stream is marked invalid and the value of `variables` is undefined.
959 ///
960 /// \pre The behavior is undefined unless `0 <= numVariables` and
961 /// `variables` has sufficient capacity.
963 int numVariables);
964
965 /// If required, throw a `TestInStreamException` (see
966 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
967 /// unsigned integer type code, verify the type of the next value in
968 /// this stream, consume that 32-bit signed integer array value into the
969 /// specified `variables` of the specified `numVariables` if its type
970 /// and length are appropriate, update the cursor location, and return a
971 /// reference to this stream. If the type is incorrect, then this
972 /// stream is marked invalid and the value of `variables` is unchanged.
973 /// If this stream is initially invalid, this operation has no effect.
974 /// If this function otherwise fails to extract a valid value, this
975 /// stream is marked invalid and the value of `variables` is undefined.
976 ///
977 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
978 /// has sufficient capacity.
979 TestInStream& getArrayInt32(int *variables, int numVariables);
980
981 /// If required, throw a `TestInStreamException` (see
982 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
983 /// unsigned integer type code, verify the type of the next value in
984 /// this stream, consume that 32-bit unsigned integer array value into
985 /// the specified `variables` of the specified `numVariables` if its
986 /// type and length are appropriate, update the cursor location, and
987 /// return a reference to this stream. If the type is incorrect, then
988 /// this stream is marked invalid and the value of `variables` is
989 /// unchanged. If this stream is initially invalid, this operation has
990 /// no effect. If this function otherwise fails to extract a valid
991 /// value, this stream is marked invalid and the value of `variables` is undefined.
992 ///
993 /// \pre The behavior is undefined unless `0 <= numVariables` and
994 /// `variables` has sufficient capacity.
995 TestInStream& getArrayUint32(unsigned int *variables, int numVariables);
996
997 /// If required, throw a `TestInStreamException` (see
998 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
999 /// unsigned integer type code, verify the type of the next value in
1000 /// this stream, consume that 24-bit signed integer array value into the
1001 /// specified `variables` of the specified `numVariables` if its type
1002 /// and length are appropriate, update the cursor location, and return a
1003 /// reference to this stream. If the type is incorrect, then this
1004 /// stream is marked invalid and the value of `variables` is unchanged.
1005 /// If this stream is initially invalid, this operation has no effect.
1006 /// If this function otherwise fails to extract a valid value, this
1007 /// stream is marked invalid and the value of `variables` is undefined.
1008 ///
1009 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
1010 /// has sufficient capacity.
1011 TestInStream& getArrayInt24(int *variables, int numVariables);
1012
1013 /// If required, throw a `TestInStreamException` (see
1014 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
1015 /// unsigned integer type code, verify the type of the next value in
1016 /// this stream, consume that 24-bit unsigned integer array value into
1017 /// the specified `variables` of the specified `numVariables` if its
1018 /// type and length are appropriate, update the cursor location, and
1019 /// return a reference to this stream. If the type is incorrect, then
1020 /// this stream is marked invalid and the value of `variables` is
1021 /// unchanged. If this stream is initially invalid, this operation has
1022 /// no effect. If this function otherwise fails to extract a valid
1023 /// value, this stream is marked invalid and the value of `variables` is undefined.
1024 ///
1025 /// \pre The behavior is undefined unless `0 <= numVariables` and
1026 /// `variables` has sufficient capacity.
1027 TestInStream& getArrayUint24(unsigned int *variables, int numVariables);
1028
1029 /// If required, throw a `TestInStreamException` (see
1030 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
1031 /// unsigned integer type code, verify the type of the next value in
1032 /// this stream, consume that 16-bit signed integer array value into the
1033 /// specified `variables` of the specified `numVariables` if its type
1034 /// and length are appropriate, update the cursor location, and return a
1035 /// reference to this stream. If the type is incorrect, then this
1036 /// stream is marked invalid and the value of `variables` is unchanged.
1037 /// If this stream is initially invalid, this operation has no effect.
1038 /// If this function otherwise fails to extract a valid value, this
1039 /// stream is marked invalid and the value of `variables` is undefined.
1040 ///
1041 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
1042 /// has sufficient capacity.
1043 TestInStream& getArrayInt16(short *variables, int numVariables);
1044
1045 /// If required, throw a `TestInStreamException` (see
1046 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
1047 /// unsigned integer type code, verify the type of the next value in
1048 /// this stream, consume that 16-bit unsigned integer array value into
1049 /// the specified `variables` of the specified `numVariables` if its
1050 /// type and length are appropriate, update the cursor location, and
1051 /// return a reference to this stream. If the type is incorrect, then
1052 /// this stream is marked invalid and the value of `variables` is
1053 /// unchanged. If this stream is initially invalid, this operation has
1054 /// no effect. If this function otherwise fails to extract a valid
1055 /// value, this stream is marked invalid and the value of `variables` is undefined.
1056 ///
1057 /// \pre The behavior is undefined unless `0 <= numVariables` and
1058 /// `variables` has sufficient capacity.
1059 TestInStream& getArrayUint16(unsigned short *variables, int numVariables);
1060
1061 /// If required, throw a `TestInStreamException` (see
1062 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
1063 /// unsigned integer type code, verify the type of the next value in
1064 /// this stream, consume that 8-bit signed integer array value into the
1065 /// specified `variables` of the specified `numVariables` if its type
1066 /// and length are appropriate, update the cursor location, and return a
1067 /// reference to this stream. If the type is incorrect, then this
1068 /// stream is marked invalid and the value of `variables` is unchanged.
1069 /// If this stream is initially invalid, this operation has no effect.
1070 /// If this function otherwise fails to extract a valid value, this
1071 /// stream is marked invalid and the value of `variables` is undefined.
1072 ///
1073 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables`
1074 /// has sufficient capacity.
1075 TestInStream& getArrayInt8(char *variables, int numVariables);
1076 TestInStream& getArrayInt8(signed char *variables, int numVariables);
1077
1078 /// If required, throw a `TestInStreamException` (see
1079 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
1080 /// unsigned integer type code, verify the type of the next value in
1081 /// this stream, consume that 8-bit unsigned integer array value into
1082 /// the specified `variables` of the specified `numVariables` if its
1083 /// type and length are appropriate, update the cursor location, and
1084 /// return a reference to this stream. If the type is incorrect, then
1085 /// this stream is marked invalid and the value of `variables` is
1086 /// unchanged. If this stream is initially invalid, this operation has
1087 /// no effect. If this function otherwise fails to extract a valid
1088 /// value, this stream is marked invalid and the value of `variables` is undefined.
1089 ///
1090 /// \pre The behavior is undefined unless `0 <= numVariables` and
1091 /// `variables` has sufficient capacity.
1092 TestInStream& getArrayUint8(char *variables, int numVariables);
1093 TestInStream& getArrayUint8(unsigned char *variables, int numVariables);
1094
1095 // *** arrays of floating-point values ***
1096
1097 /// If required, throw a `TestInStreamException` (see
1098 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
1099 /// unsigned integer type code, verify the type of the next value in
1100 /// this stream, consume that IEEE double-precision (8-byte)
1101 /// floating-point array value into the specified `variables` of the
1102 /// specified `numVariables` if its type and length are appropriate,
1103 /// update the cursor location, and return a reference to this stream.
1104 /// If the type is incorrect, then this stream is marked invalid and the
1105 /// value of `variables` is unchanged. If this stream is initially
1106 /// invalid, this operation has no effect. If this function otherwise
1107 /// fails to extract a valid value, this stream is marked invalid and
1108 /// the value of `variables` is undefined.
1109 ///
1110 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
1111 ///
1112 /// \note Note that for non-conforming platforms, this operation may be lossy.
1113 TestInStream& getArrayFloat64(double *variables, int numVariables);
1114
1115 /// If required, throw a `TestInStreamException` (see
1116 /// `throwExceptionIfInputLimitExhausted`); otherwise, consume the 8-bit
1117 /// unsigned integer type code, verify the type of the next value in
1118 /// this stream, consume that IEEE single-precision (4-byte)
1119 /// floating-point array value into the specified `variables` of the
1120 /// specified `numVariables` if its type and length are appropriate,
1121 /// update the cursor location, and return a reference to this stream.
1122 /// If the type is incorrect, then this stream is marked invalid and the
1123 /// value of `variables` is unchanged. If this stream is initially
1124 /// invalid, this operation has no effect. If this function otherwise
1125 /// fails to extract a valid value, this stream is marked invalid and
1126 /// the value of `variables` is undefined.
1127 ///
1128 /// \pre The behavior is undefined unless `0 <= numVariables` and `variables` has sufficient capacity.
1129 ///
1130 /// \note Note that for non-conforming platforms, this operation may be lossy.
1131 TestInStream& getArrayFloat32(float *variables, int numVariables);
1132
1133 // ACCESSORS
1134
1135 /// Return a non-zero value if this stream is valid, and 0 otherwise. An
1136 /// invalid stream is a stream for which an input operation was detected to
1137 /// have failed.
1138 operator const void *() const;
1139
1140 /// Return the index of the next byte to be extracted from this stream.
1141 bsl::size_t cursor() const;
1142
1143 /// Return the address of the contiguous, non-modifiable external memory
1144 /// buffer of this stream. The behavior of accessing elements outside the
1145 /// range `[ data() .. data() + (length() - 1) ]` is undefined.
1146 const char *data() const;
1147
1148 /// Return the current number of input requests left before an exception is
1149 /// thrown. A negative value indicates that no exception is scheduled.
1150 int inputLimit() const;
1151
1152 /// Return `true` if this stream is empty, and `false` otherwise.
1153 ///
1154 /// \note Note that this function enables higher-level types to verify that, after
1155 /// successfully reading all expected data, no data remains.
1156 bool isEmpty() const;
1157
1158 /// Return `true` if this stream's quiet mode is ON, and `false` otherwise.
1159 bool isQuiet() const;
1160
1161 /// Return `true` if this stream is valid, and `false` otherwise. An
1162 /// invalid stream is a stream in which insufficient or invalid data was detected during an extraction operation.
1163 ///
1164 /// \note Note that an empty stream
1165 /// will be valid unless an extraction attempt or explicit invalidation
1166 /// causes it to be otherwise.
1167 bool isValid() const;
1168
1169 /// Return the total number of bytes stored in the external memory buffer.
1170 bsl::size_t length() const;
1171};
1172
1173// FREE OPERATORS
1174
1175/// Write the specified `object` to the specified output `stream` in some
1176/// reasonable (multi-line) format, and return a reference to `stream`.
1177bsl::ostream& operator<<(bsl::ostream& stream, const TestInStream& object);
1178
1179/// Read the specified `value` from the specified input `stream` following the
1180/// requirements of the BDEX protocol (see the `bslx` package-level
1181/// documentation), and return a reference to `stream`.
1182///
1183/// \pre The behavior is undefined unless `TYPE` is BDEX-compliant.
1184template <class TYPE>
1185TestInStream& operator>>(TestInStream& stream, TYPE& value);
1186
1187} // close package namespace
1188
1189 // ============================================
1190 // macro BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN
1191 // ============================================
1192
1193#ifdef BDE_BUILD_TARGET_EXC
1194
1195namespace bslx {
1196
1197/// This class provides a common base class for the parameterized `TestInStream_Proxy` class (below).
1198///
1199/// \note Note that the `virtual`
1200/// `setInputLimit` method, although a "setter", *must* be declared `const`.
1201///
1202/// See @ref bslx_testinstream
1203class TestInStream_ProxyBase {
1204
1205 public:
1206 virtual ~TestInStream_ProxyBase()
1207 {
1208 }
1209
1210 // ACCESSORS
1211 virtual void setInputLimit(int limit) const = 0;
1212};
1213
1214/// This class provides a proxy to the test stream that is supplied to the
1215/// `BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN` macro. This proxy may be
1216/// instantiated with `TestInStream`, or with a type that supports the same
1217/// interface as `TestInStream`.
1218///
1219/// See @ref bslx_testinstream
1220template <class BSLX_STREAM_TYPE>
1221class TestInStream_Proxy: public TestInStream_ProxyBase {
1222
1223 // DATA
1224 BSLX_STREAM_TYPE *d_stream_p; // stream used in '*_BEGIN' and
1225 // '*_END' macros (held, not owned)
1226
1227 public:
1228 // CREATORS
1229 TestInStream_Proxy(BSLX_STREAM_TYPE *stream)
1230 : d_stream_p(stream)
1231 {
1232 }
1233
1234 ~TestInStream_Proxy() BSLS_KEYWORD_OVERRIDE
1235 {
1236 }
1237
1238 // ACCESSORS
1239 void setInputLimit(int limit) const BSLS_KEYWORD_OVERRIDE
1240 {
1241 d_stream_p->setInputLimit(limit);
1242 }
1243};
1244
1245/// Return, by value, a test stream proxy for the specified parameterized
1246/// `stream`.
1247template <class BSLX_STREAM_TYPE>
1248inline
1249TestInStream_Proxy<BSLX_STREAM_TYPE>
1250TestInStream_getProxy(BSLX_STREAM_TYPE *stream)
1251{
1252 return TestInStream_Proxy<BSLX_STREAM_TYPE>(stream);
1253}
1254
1255} // close package namespace
1256
1257#ifndef BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN
1258#define BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN(BSLX_TESTINSTREAM) \
1259{ \
1260 const bslx::TestInStream_ProxyBase& testInStream = \
1261 bslx::TestInStream_getProxy(&BSLX_TESTINSTREAM); \
1262 { \
1263 static int firstTime = 1; \
1264 if (veryVerbose && firstTime) bsl::cout << \
1265 "### BSLX EXCEPTION TEST -- (ENABLED) --" << '\n'; \
1266 firstTime = 0; \
1267 } \
1268 if (veryVeryVerbose) bsl::cout << \
1269 "### Begin BSLX exception test." << '\n'; \
1270 int bslxExceptionCounter = 0; \
1271 static int bslxExceptionLimit = 100; \
1272 testInStream.setInputLimit(bslxExceptionCounter); \
1273 do { \
1274 try {
1275#endif // BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN
1276
1277#else // !defined(BDE_BUILD_TARGET_EXC)
1278
1279#ifndef BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN
1280#define BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN(testInStream) \
1281{ \
1282 static int firstTime = 1; \
1283 if (verbose && firstTime) { \
1284 bsl::cout << "### BSLX EXCEPTION TEST -- (NOT ENABLED) --" << '\n'; \
1285 firstTime = 0; \
1286 } \
1287}
1288#endif // BSLX_TESTINSTREAM_EXCEPTION_TEST_BEGIN
1289
1290#endif // BDE_BUILD_TARGET_EXC
1291
1292 // ==========================================
1293 // macro BSLX_TESTINSTREAM_EXCEPTION_TEST_END
1294 // ==========================================
1295
1296#ifdef BDE_BUILD_TARGET_EXC
1297
1298#ifndef BSLX_TESTINSTREAM_EXCEPTION_TEST_END
1299#define BSLX_TESTINSTREAM_EXCEPTION_TEST_END \
1300 } catch (bslx::TestInStreamException& e) { \
1301 if ((veryVerbose && bslxExceptionLimit) || veryVeryVerbose) \
1302 { \
1303 --bslxExceptionLimit; \
1304 bsl::cout << "(" << bslxExceptionCounter << ')'; \
1305 if (veryVeryVerbose) { \
1306 bsl::cout << " BSLX EXCEPTION: " \
1307 << "input limit = " \
1308 << bslxExceptionCounter \
1309 << ", " \
1310 << "last data type = " \
1311 << e.dataType(); \
1312 } \
1313 else if (0 == bslxExceptionLimit) { \
1314 bsl::cout << " [ Note: 'bslxExceptionLimit' reached. ]"; \
1315 } \
1316 bsl::cout << '\n'; \
1317 } \
1318 testInStream.setInputLimit(++bslxExceptionCounter); \
1319 continue; \
1320 } \
1321 testInStream.setInputLimit(-1); \
1322 break; \
1323 } while (1); \
1324 if (veryVeryVerbose) { \
1325 bsl::cout << "### End BSLX exception test." << '\n'; \
1326 } \
1327}
1328#endif // BSLX_TESTINSTREAM_EXCEPTION_TEST_END
1329
1330#else // !defined(BDE_BUILD_TARGET_EXC)
1331
1332#ifndef BSLX_TESTINSTREAM_EXCEPTION_TEST_END
1333#define BSLX_TESTINSTREAM_EXCEPTION_TEST_END
1334#endif
1335
1336#endif // BDE_BUILD_TARGET_EXC
1337
1338namespace bslx {
1339
1340// ============================================================================
1341// INLINE DEFINITIONS
1342// ============================================================================
1343
1344 // ------------------
1345 // class TestInStream
1346 // ------------------
1347
1348// PRIVATE MANIPULATORS
1349inline
1350void TestInStream::throwExceptionIfInputLimitExhausted(
1351 const TypeCode::Enum& code)
1352{
1353#ifdef BDE_BUILD_TARGET_EXC
1354 if (0 <= d_inputLimit) {
1355 --d_inputLimit;
1356 if (0 > d_inputLimit) {
1357 throw TestInStreamException(code);
1358 }
1359 }
1360#else
1361 (void)code;
1362#endif
1363}
1364
1365// MANIPULATORS
1366inline
1368{
1369 d_validFlag = false;
1370}
1371
1372inline
1374{
1375 d_validFlag = true;
1376 d_cursor = 0;
1377}
1378
1379inline
1380void TestInStream::reset(const char *buffer, bsl::size_t numBytes)
1381{
1382 BSLS_ASSERT_SAFE(buffer || 0 == numBytes);
1383
1384 d_buffer = buffer;
1385 d_numBytes = numBytes;
1386 d_validFlag = true;
1387 d_cursor = 0;
1388}
1389
1390inline
1392{
1393 d_buffer = srcData.data();
1394 d_numBytes = srcData.length();
1395 d_validFlag = true;
1396 d_cursor = 0;
1397}
1398
1399inline
1400void TestInStream::seek(bsl::size_t offset)
1401{
1402 BSLS_ASSERT_SAFE(offset <= length());
1403
1404 d_cursor = offset;
1405 d_validFlag = 1;
1406}
1407
1408inline
1410{
1411 d_inputLimit = limit;
1412}
1413
1414inline
1415void TestInStream::setQuiet(bool flagValue)
1416{
1417 d_quietFlag = flagValue;
1418}
1419
1420// ACCESSORS
1421inline
1422TestInStream::operator const void *() const
1423{
1424 return isValid() ? this : 0;
1425}
1426
1427inline
1428bsl::size_t TestInStream::cursor() const
1429{
1430 return d_cursor;
1431}
1432
1433inline
1434const char *TestInStream::data() const
1435{
1436 return d_numBytes ? d_buffer : 0;
1437}
1438
1439inline
1441{
1442 return d_inputLimit;
1443}
1444
1445inline
1447{
1448 return cursor() >= length();
1449}
1450
1451inline
1453{
1454 return d_quietFlag;
1455}
1456
1457inline
1459{
1460 return d_validFlag;
1461}
1462
1463inline
1464bsl::size_t TestInStream::length() const
1465{
1466 return d_numBytes;
1467}
1468
1469template <class TYPE>
1470inline
1472{
1473 return InStreamFunctions::bdexStreamIn(stream, value);
1474}
1475
1476} // close package namespace
1477
1478
1479#endif
1480
1481// ----------------------------------------------------------------------------
1482// Copyright 2014 Bloomberg Finance L.P.
1483//
1484// Licensed under the Apache License, Version 2.0 (the "License");
1485// you may not use this file except in compliance with the License.
1486// You may obtain a copy of the License at
1487//
1488// http://www.apache.org/licenses/LICENSE-2.0
1489//
1490// Unless required by applicable law or agreed to in writing, software
1491// distributed under the License is distributed on an "AS IS" BASIS,
1492// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1493// See the License for the specific language governing permissions and
1494// limitations under the License.
1495// ----------------------------- END-OF-FILE ----------------------------------
1496
1497/** @} */
1498/** @} */
1499/** @} */
Definition bslstl_string.h:1252
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_testinstream.h:413
TestInStream(const bslstl::StringRef &srcData)
Create a test input stream containing the specified srcData.
TestInStream & getUint64(bsls::Types::Uint64 &variable)
void reset()
Definition bslx_testinstream.h:1373
TestInStream & getArrayFloat64(double *variables, int numVariables)
TestInStream & getInt56(bsls::Types::Int64 &variable)
TestInStream & getInt24(int &variable)
TestInStream & getArrayUint8(unsigned char *variables, int numVariables)
TestInStream & getArrayFloat32(float *variables, int numVariables)
friend bsl::ostream & operator<<(bsl::ostream &, const TestInStream &)
TestInStream & getLength(int &variable)
TestInStream & getArrayUint32(unsigned int *variables, int numVariables)
TestInStream & getArrayInt8(signed char *variables, int numVariables)
TestInStream & getString(bsl::string &variable)
bool isQuiet() const
Return true if this stream's quiet mode is ON, and false otherwise.
Definition bslx_testinstream.h:1452
TestInStream & getFloat32(float &variable)
TestInStream & getArrayUint40(bsls::Types::Uint64 *variables, int numVariables)
TestInStream & getInt64(bsls::Types::Int64 &variable)
TestInStream & getUint16(unsigned short &variable)
TestInStream & getArrayUint8(char *variables, int numVariables)
void invalidate()
Definition bslx_testinstream.h:1367
bool isEmpty() const
Definition bslx_testinstream.h:1446
TestInStream(const char *buffer, bsl::size_t numBytes)
TestInStream & getArrayUint64(bsls::Types::Uint64 *variables, int numVariables)
TestInStream & getInt40(bsls::Types::Int64 &variable)
bsl::size_t length() const
Return the total number of bytes stored in the external memory buffer.
Definition bslx_testinstream.h:1464
TestInStream & getInt48(bsls::Types::Int64 &variable)
TestInStream & getUint32(unsigned int &variable)
TestInStream & getArrayUint48(bsls::Types::Uint64 *variables, int numVariables)
TestInStream & getArrayUint56(bsls::Types::Uint64 *variables, int numVariables)
int inputLimit() const
Definition bslx_testinstream.h:1440
~TestInStream()
Destroy this test input stream.
TestInStream & getUint40(bsls::Types::Uint64 &variable)
TestInStream & getInt32(int &variable)
TestInStream & getVersion(int &variable)
TestInStream & getArrayInt16(short *variables, int numVariables)
TestInStream & getArrayInt56(bsls::Types::Int64 *variables, int numVariables)
TestInStream & getArrayInt32(int *variables, int numVariables)
TestInStream & getArrayInt48(bsls::Types::Int64 *variables, int numVariables)
TestInStream & getArrayInt8(char *variables, int numVariables)
TestInStream & getArrayInt40(bsls::Types::Int64 *variables, int numVariables)
TestInStream & getUint8(unsigned char &variable)
TestInStream & getArrayInt64(bsls::Types::Int64 *variables, int numVariables)
void seek(bsl::size_t offset)
Definition bslx_testinstream.h:1400
void setInputLimit(int limit)
Definition bslx_testinstream.h:1409
TestInStream & getArrayInt24(int *variables, int numVariables)
bool isValid() const
Definition bslx_testinstream.h:1458
const char * data() const
Definition bslx_testinstream.h:1434
TestInStream & getArrayUint16(unsigned short *variables, int numVariables)
bsl::size_t cursor() const
Return the index of the next byte to be extracted from this stream.
Definition bslx_testinstream.h:1428
TestInStream & getUint8(char &variable)
TestInStream & getUint56(bsls::Types::Uint64 &variable)
TestInStream & getInt16(short &variable)
TestInStream & getArrayUint24(unsigned int *variables, int numVariables)
TestInStream & getInt8(char &variable)
TestInStream & getUint48(bsls::Types::Uint64 &variable)
TestInStream & getFloat64(double &variable)
void setQuiet(bool flagValue)
Definition bslx_testinstream.h:1415
TestInStream & getUint24(unsigned int &variable)
TestInStream & getInt8(signed char &variable)
#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_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
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
Enum
Definition bslx_typecode.h:158