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