BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslx_genericoutstream.h
Go to the documentation of this file.
1/// @file bslx_genericoutstream.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslx_genericoutstream.h -*-C++-*-
8#ifndef INCLUDED_BSLX_GENERICOUTSTREAM
9#define INCLUDED_BSLX_GENERICOUTSTREAM
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslx_genericoutstream bslx_genericoutstream
15/// @brief Externalization of fundamental types to a parameterized stream.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslx
19/// @{
20/// @addtogroup bslx_genericoutstream
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslx_genericoutstream-purpose"> Purpose</a>
25/// * <a href="#bslx_genericoutstream-classes"> Classes </a>
26/// * <a href="#bslx_genericoutstream-description"> Description </a>
27/// * <a href="#bslx_genericoutstream-generic-byte-format-generator"> Generic Byte-Format Generator </a>
28/// * <a href="#bslx_genericoutstream-versioning"> Versioning </a>
29/// * <a href="#bslx_genericoutstream-usage"> Usage </a>
30/// * <a href="#bslx_genericoutstream-example-1-basic-externalization"> Example 1: Basic Externalization </a>
31/// * <a href="#bslx_genericoutstream-example-2-sample-streambuf-implementation"> Example 2: Sample STREAMBUF Implementation </a>
32///
33/// # Purpose {#bslx_genericoutstream-purpose}
34/// Externalization of fundamental types to a parameterized stream.
35///
36/// # Classes {#bslx_genericoutstream-classes}
37///
38/// - bslx::GenericOutStream: parameterized output stream for fundamentals
39///
40/// @see bslx_streambufoutstream, bslx_genericinstream
41///
42/// # Description {#bslx_genericoutstream-description}
43/// This component implements a parameterized output stream
44/// class, `bslx::GenericOutStream`, that provides platform-independent output
45/// methods ("externalization") on values, and arrays of values, of fundamental
46/// types, and on `bsl::string`.
47///
48/// This component is intended to be used in conjunction with the
49/// @ref bslx_genericinstream "unexternalization" component. Each output method of
50/// `bslx::GenericOutStream` writes either a value or a homogeneous array of
51/// values of a fundamental type, in a format that is readable by the
52/// corresponding `bslx::GenericInStream` method. In general, the user cannot
53/// rely on any other mechanism to read data written by `bslx::GenericOutStream`
54/// unless that mechanism explicitly states its ability to do so.
55///
56/// The supported types and required content are listed in the `bslx`
57/// package-level documentation under "Supported Types".
58///
59/// Note that the values are stored in big-endian (i.e., network byte order)
60/// format.
61///
62/// Note that output streams can be *invalidated* explicitly and queried for
63/// *validity*. Writing to an initially invalid stream has no effect. Whenever
64/// an output operation fails, the stream should be invalidated explicitly.
65///
66/// ## Generic Byte-Format Generator {#bslx_genericoutstream-generic-byte-format-generator}
67///
68///
69/// The class `bslx::GenericOutStream` is parameterized by a buffered stream
70/// class, `STREAMBUF`, which, given the declarations:
71/// @code
72/// char c;
73/// int len;
74/// const char *s;
75/// STREAMBUF *sb;
76/// @endcode
77/// must make the following expressions syntactically valid, with the assert
78/// statements highlighting the expected return values:
79/// @code
80/// STREAMBUF::traits_type::int_type eof = STREAMBUF::traits_type::eof();
81/// assert(eof != sb->sputc(c));
82/// assert(len == sb->sputn(s, len));
83/// assert( 0 == sb->pubsync());
84/// @endcode
85/// Suitable choices for `STREAMBUF` include any class that implements the
86/// `bsl::basic_streambuf` protocol.
87///
88/// The class `bslx::StreambufOutStream` is a `typedef` of
89/// `bslx::GenericOutStream<bsl::streambuf>`.
90///
91/// ## Versioning {#bslx_genericoutstream-versioning}
92///
93///
94/// BDEX provides two concepts that support versioning the BDEX serialization
95/// format of a type: `version` and `versionSelector`. A `version` is a 1-based
96/// integer indicating one of the supported formats (e.g., format 1, format 2,
97/// etc.). A `versionSelector` is a value that is mapped to a `version` for a
98/// type by the type's implementation of `maxSupportedBdexVersion`.
99///
100/// Selecting a value for a `versionSelector` is required at two different
101/// points: (1) when implementing a new `version` format within the
102/// `bdexStreamIn` and `bdexStreamOut` methods of a type, and (2) when
103/// implementing code that constructs a BDEX `OutStream`. In both cases, the
104/// value should be a *compile*-time-selected value.
105///
106/// When a new `version` format is implemented within the `bdexStreamIn` and
107/// `bdexStreamOut` methods of a type, a new mapping in
108/// `maxSupportedBdexVersion` should be created to expose this new `version`
109/// with a `versionSelector`. A simple - and the recommended - approach is to
110/// use a value having the pattern "YYYYMMDD", where "YYYYMMDD" corresponds to
111/// the "go-live" date of the corresponding `version` format.
112///
113/// When constructing an `OutStream`, a simple approach is to use the current
114/// date as a *compile*-time constant value. In combination with the
115/// recommended selection of `versionSelector` values for
116/// `maxSupportedBdexVersion`, this will result in consistent and predictable
117/// behavior while externalizing types. Note that this recommendation is chosen
118/// for its simplicity: to ensure the largest possible audience for an
119/// externalized representation, clients can select the minimum date value that
120/// will result in the desired version of all types externalized with
121/// `operator<<` being selected.
122///
123/// See the `bslx` package-level documentation for more detailed information
124/// about versioning.
125///
126/// ## Usage {#bslx_genericoutstream-usage}
127///
128///
129/// This section illustrates intended use of this component. The first example
130/// depicts usage with a `bsl::stringbuf`. The second example replaces the
131/// `bsl::stringbuf` with a user-defined `STREAMBUF`.
132///
133/// ### Example 1: Basic Externalization {#bslx_genericoutstream-example-1-basic-externalization}
134///
135///
136/// A `bslx::GenericOutStream` can be used to externalize values in a
137/// platform-neutral way. Writing out fundamental C++ types and `bsl::string`
138/// requires no additional work on the part of the client; the client can simply
139/// use the stream directly. The following code serializes a few representative
140/// values using a `bslx::GenericOutStream`, compares the contents of this
141/// stream to the expected value, and then writes the contents of this stream's
142/// buffer to `stdout`.
143///
144/// First, we create a `bslx::GenericOutStream`, with an arbitrary value for its
145/// `versionSelector`, and externalize some values:
146/// @code
147/// bsl::stringbuf buffer1;
148/// bslx::GenericOutStream<bsl::stringbuf> outStream1(&buffer1, 20131127);
149/// outStream1.putInt32(1);
150/// outStream1.putInt32(2);
151/// outStream1.putInt8('c');
152/// outStream1.putString(bsl::string("hello"));
153/// @endcode
154/// Then, we compare the contents of the buffer to the expected value:
155/// @code
156/// bsl::string theChars = buffer1.str();
157/// assert(15 == theChars.size());
158/// assert( 0 == bsl::memcmp(theChars.data(),
159/// "\x00\x00\x00\x01\x00\x00\x00\x02""c\x05""hello",
160/// 15));
161/// @endcode
162/// Finally, we print the buffer's contents to `bsl::cout`.
163/// @code
164/// for (bsl::size_t i = 0; i < theChars.size(); ++i) {
165/// if (bsl::isalnum(static_cast<unsigned char>(theChars[i]))) {
166/// bsl::cout << "nextByte (char): " << theChars[i] << bsl::endl;
167/// }
168/// else {
169/// bsl::cout << "nextByte (int): "
170/// << static_cast<int>(theChars[i])
171/// << bsl::endl;
172/// }
173/// }
174/// @endcode
175/// Executing the above code results in the following output:
176/// @code
177/// nextByte (int): 0
178/// nextByte (int): 0
179/// nextByte (int): 0
180/// nextByte (int): 1
181/// nextByte (int): 0
182/// nextByte (int): 0
183/// nextByte (int): 0
184/// nextByte (int): 2
185/// nextByte (char): c
186/// nextByte (int): 5
187/// nextByte (char): h
188/// nextByte (char): e
189/// nextByte (char): l
190/// nextByte (char): l
191/// nextByte (char): o
192/// @endcode
193/// See the @ref bslx_genericinstream component usage example for a more practical
194/// example of using `bslx` streams.
195///
196/// ### Example 2: Sample STREAMBUF Implementation {#bslx_genericoutstream-example-2-sample-streambuf-implementation}
197///
198///
199/// For this example, we will implement `MyOutStreamBuf`, a minimal `STREAMBUF`
200/// to be used with `bslx::GenericOutStream`. The implementation will consist
201/// of only what is required of the type and two accessors to verify correct
202/// functionality (`data` and `length`).
203///
204/// First, we implement `MyOutStreamBuf` (which, for brevity, simply uses the
205/// default allocator):
206/// @code
207/// class MyOutStreamBuf {
208/// // This class implements a very basic stream buffer suitable for use in
209/// // 'bslx::GenericOutStream'.
210///
211/// // DATA
212/// bsl::string d_buffer; // output buffer
213///
214/// private:
215/// // NOT IMPLEMENTED
216/// MyOutStreamBuf(const MyOutStreamBuf&);
217/// MyOutStreamBuf& operator=(const MyOutStreamBuf&);
218///
219/// public:
220/// // TYPES
221/// struct traits_type {
222/// static int eof() { return -1; }
223/// };
224///
225/// // CREATORS
226/// MyOutStreamBuf();
227/// // Create an empty stream buffer.
228///
229/// ~MyOutStreamBuf();
230/// // Destroy this stream buffer.
231///
232/// // MANIPULATORS
233/// int pubsync();
234/// // Return 0.
235///
236/// int sputc(char c);
237/// // Write the specified character 'c' to this buffer. Return 'c' on
238/// // success, and 'traits_type::eof()' otherwise.
239///
240/// bsl::streamsize sputn(const char *s, bsl::streamsize length);
241/// // Write the specified 'length' characters at the specified address
242/// // 's' to this buffer, and return the number of characters written.
243///
244/// // ACCESSORS
245/// const char *data() const;
246/// // Return the address of the non-modifiable character buffer held
247/// // by this stream buffer.
248///
249/// bsl::streamsize size() const;
250/// // Return the number of characters from the beginning of the buffer
251/// // to the current write position.
252/// };
253///
254/// // ========================================================================
255/// // INLINE FUNCTION DEFINITIONS
256/// // ========================================================================
257///
258/// // CREATORS
259/// MyOutStreamBuf::MyOutStreamBuf()
260/// : d_buffer()
261/// {
262/// }
263///
264/// MyOutStreamBuf::~MyOutStreamBuf()
265/// {
266/// }
267///
268/// // MANIPULATORS
269/// int MyOutStreamBuf::pubsync()
270/// {
271/// // In this implementation, there is nothing to be done except return
272/// // success.
273///
274/// return 0;
275/// }
276///
277/// int MyOutStreamBuf::sputc(char c)
278/// {
279/// d_buffer += c;
280/// return static_cast<int>(c);
281/// }
282///
283/// bsl::streamsize MyOutStreamBuf::sputn(const char *s,
284/// bsl::streamsize length)
285/// {
286/// d_buffer.append(s, length);
287/// return length;
288/// }
289///
290/// // ACCESSORS
291/// const char *MyOutStreamBuf::data() const
292/// {
293/// return d_buffer.data();
294/// }
295///
296/// bsl::streamsize MyOutStreamBuf::size() const
297/// {
298/// return d_buffer.size();
299/// }
300/// @endcode
301/// Then, we create `buffer2`, an instance of `MyOutStreamBuf`, and a
302/// `bslx::GenericOutStream` using `buffer2`, with an arbitrary value for its
303/// `versionSelector`, and externalize some values:
304/// @code
305/// MyOutStreamBuf buffer2;
306/// bslx::GenericOutStream<MyOutStreamBuf> outStream2(&buffer2, 20131127);
307/// outStream2.putInt32(1);
308/// outStream2.putInt32(2);
309/// outStream2.putInt8('c');
310/// outStream2.putString(bsl::string("hello"));
311/// @endcode
312/// Finally, we compare the contents of the buffer to the expected value:
313/// @code
314/// assert(15 == buffer2.size());
315/// assert( 0 == bsl::memcmp(buffer2.data(),
316/// "\x00\x00\x00\x01\x00\x00\x00\x02""c\x05""hello",
317/// 15));
318/// @endcode
319/// @}
320/** @} */
321/** @} */
322
323/** @addtogroup bsl
324 * @{
325 */
326/** @addtogroup bslx
327 * @{
328 */
329/** @addtogroup bslx_genericoutstream
330 * @{
331 */
332
333#include <bslscm_version.h>
334
336
337#include <bsls_assert.h>
338#include <bsls_performancehint.h>
339#include <bsls_platform.h>
340#include <bsls_types.h>
341
342#include <bsl_cstddef.h>
343#include <bsl_string.h>
344#include <bsl_vector.h>
345
346
347namespace bslx {
348
349 // ======================
350 // class GenericOutStream
351 // ======================
352
353/// This class provides output methods to externalize values, and C-style
354/// arrays of values, of the fundamental integral and floating-point types,
355/// as well as `bsl::string` values. In particular, each `put` method of
356/// this class is guaranteed to write stream data that can be read by the
357/// corresponding `get` method of `bslx::GenericInStream`. See the `bslx`
358/// package-level documentation for the definition of the BDEX `OutStream`
359/// protocol.
360///
361/// See @ref bslx_genericoutstream
362template <class STREAMBUF>
364
365 // PRIVATE TYPES
366 enum {
367 // Enumerate the platform-independent sizes (in bytes) of data types in
368 // wire format. Note that the wire format size may differ from the
369 // size in memory.
370
371 k_SIZEOF_INT64 = 8,
372 k_SIZEOF_INT56 = 7,
373 k_SIZEOF_INT48 = 6,
374 k_SIZEOF_INT40 = 5,
375 k_SIZEOF_INT32 = 4,
376 k_SIZEOF_INT24 = 3,
377 k_SIZEOF_INT16 = 2,
378 k_SIZEOF_INT8 = 1,
379 k_SIZEOF_FLOAT64 = 8,
380 k_SIZEOF_FLOAT32 = 4
381 };
382
383 // DATA
384 STREAMBUF *d_streamBuf; // held stream to write to
385
386 int d_versionSelector; // 'versionSelector' to use with
387 // 'operator<<' as per the 'bslx'
388 // package-level documentation
389
390 int d_validFlag; // stream validity flag; 'true' if stream is
391 // in valid state, 'false' otherwise
392
393 // NOT IMPLEMENTED
395 GenericOutStream& operator=(const GenericOutStream&);
396
397 private:
398 // PRIVATE MANIPULATORS
399
400 /// Put this output stream into a valid state. This function has no
401 /// effect if this stream is already valid.
402 void validate();
403
404 public:
405 // CREATORS
406
407 /// Create an output byte stream that writes its output to the specified
408 /// `streamBuf` and uses the specified (*compile*-time-defined)
409 /// `versionSelector` as needed (see {Versioning}). Note that the
410 /// `versionSelector` is expected to be formatted as "YYYYMMDD", a date
411 /// representation.
412 GenericOutStream(STREAMBUF *streamBuf, int versionSelector);
413
414 /// Destroy this object.
416
417 // MANIPULATORS
418
419 /// If this stream is valid, invoke the `pubsync` method on the
420 /// underlying stream supplied at construction of this object;
421 /// otherwise, this function has no effect.
423
424 /// Put this output stream in an invalid state. This function has no
425 /// effect if this stream is already invalid.
426 void invalidate();
427
428 /// If the specified `length` is less than 128, write to the stream
429 /// supplied at construction the one-byte integer comprised of the
430 /// least-significant one byte of the `length`; otherwise, write to the
431 /// stream the four-byte, two's complement integer (in network byte
432 /// order) comprised of the least-significant four bytes of the `length`
433 /// (in host byte order) with the most-significant bit set. Return a
434 /// reference to this stream. If this stream is initially invalid, this
435 /// operation has no effect. The behavior is undefined unless
436 /// `0 <= length`.
437 GenericOutStream& putLength(int length);
438
439 /// Write to the stream supplied at construction the one-byte, two's
440 /// complement unsigned integer comprised of the least-significant one
441 /// byte of the specified `version`, and return a reference to this
442 /// stream. If this stream is initially invalid, this operation has no
443 /// effect.
444 GenericOutStream& putVersion(int version);
445
446 // *** scalar integer values ***
447
448 /// Write to the stream supplied at construction the eight-byte, two's
449 /// complement integer (in network byte order) comprised of the
450 /// least-significant eight bytes of the specified `value` (in host byte
451 /// order), and return a reference to this stream. If this stream is
452 /// initially invalid, this operation has no effect.
454
455 /// Write to the stream supplied at construction the eight-byte, two's
456 /// complement unsigned integer (in network byte order) comprised of the
457 /// least-significant eight bytes of the specified `value` (in host byte
458 /// order), and return a reference to this stream. If this stream is
459 /// initially invalid, this operation has no effect.
461
462 /// Write to the stream supplied at construction the seven-byte, two's
463 /// complement integer (in network byte order) comprised of the
464 /// least-significant seven bytes of the specified `value` (in host byte
465 /// order), and return a reference to this stream. If this stream is
466 /// initially invalid, this operation has no effect.
468
469 /// Write to the stream supplied at construction the seven-byte, two's
470 /// complement unsigned integer (in network byte order) comprised of the
471 /// least-significant seven bytes of the specified `value` (in host byte
472 /// order), and return a reference to this stream. If this stream is
473 /// initially invalid, this operation has no effect.
475
476 /// Write to the stream supplied at construction the six-byte, two's
477 /// complement integer (in network byte order) comprised of the
478 /// least-significant six bytes of the specified `value` (in host byte
479 /// order), and return a reference to this stream. If this stream is
480 /// initially invalid, this operation has no effect.
482
483 /// Write to the stream supplied at construction the six-byte, two's
484 /// complement unsigned integer (in network byte order) comprised of the
485 /// least-significant six bytes of the specified `value` (in host byte
486 /// order), and return a reference to this stream. If this stream is
487 /// initially invalid, this operation has no effect.
489
490 /// Write to the stream supplied at construction the five-byte, two's
491 /// complement integer (in network byte order) comprised of the
492 /// least-significant five bytes of the specified `value` (in host byte
493 /// order), and return a reference to this stream. If this stream is
494 /// initially invalid, this operation has no effect.
496
497 /// Write to the stream supplied at construction the five-byte, two's
498 /// complement unsigned integer (in network byte order) comprised of the
499 /// least-significant five bytes of the specified `value` (in host byte
500 /// order), and return a reference to this stream. If this stream is
501 /// initially invalid, this operation has no effect.
503
504 /// Write to the stream supplied at construction the four-byte, two's
505 /// complement integer (in network byte order) comprised of the
506 /// least-significant four bytes of the specified `value` (in host byte
507 /// order), and return a reference to this stream. If this stream is
508 /// initially invalid, this operation has no effect.
509 GenericOutStream& putInt32(int value);
510
511 /// Write to the stream supplied at construction the four-byte, two's
512 /// complement unsigned integer (in network byte order) comprised of the
513 /// least-significant four bytes of the specified `value` (in host byte
514 /// order), and return a reference to this stream. If this stream is
515 /// initially invalid, this operation has no effect.
516 GenericOutStream& putUint32(unsigned int value);
517
518 /// Write to the stream supplied at construction the three-byte, two's
519 /// complement integer (in network byte order) comprised of the
520 /// least-significant three bytes of the specified `value` (in host byte
521 /// order), and return a reference to this stream. If this stream is
522 /// initially invalid, this operation has no effect.
523 GenericOutStream& putInt24(int value);
524
525 /// Write to the stream supplied at construction the three-byte, two's
526 /// complement unsigned integer (in network byte order) comprised of the
527 /// least-significant three bytes of the specified `value` (in host byte
528 /// order), and return a reference to this stream. If this stream is
529 /// initially invalid, this operation has no effect.
530 GenericOutStream& putUint24(unsigned int value);
531
532 /// Write to the stream supplied at construction the two-byte, two's
533 /// complement integer (in network byte order) comprised of the
534 /// least-significant two bytes of the specified `value` (in host byte
535 /// order), and return a reference to this stream. If this stream is
536 /// initially invalid, this operation has no effect.
537 GenericOutStream& putInt16(int value);
538
539 /// Write to the stream supplied at construction the two-byte, two's
540 /// complement unsigned integer (in network byte order) comprised of the
541 /// least-significant two bytes of the specified `value` (in host byte
542 /// order), and return a reference to this stream. If this stream is
543 /// initially invalid, this operation has no effect.
544 GenericOutStream& putUint16(unsigned int value);
545
546 /// Write to the stream supplied at construction the one-byte, two's
547 /// complement integer comprised of the least-significant one byte of
548 /// the specified `value`, and return a reference to this stream. If
549 /// this stream is initially invalid, this operation has no effect.
550 GenericOutStream& putInt8(int value);
551
552 /// Write to the stream supplied at construction the one-byte, two's
553 /// complement unsigned integer comprised of the least-significant one
554 /// byte of the specified `value`, and return a reference to this
555 /// stream. If this stream is initially invalid, this operation has no
556 /// effect.
557 GenericOutStream& putUint8(unsigned int value);
558
559 // *** scalar floating-point values ***
560
561 /// Write to the stream supplied at construction the eight-byte IEEE
562 /// double-precision floating-point number (in network byte order)
563 /// comprised of the most-significant eight bytes of the specified
564 /// `value` (in host byte order), and return a reference to this stream.
565 /// If this stream is initially invalid, this operation has no effect.
566 /// Note that for non-conforming platforms, this operation may be lossy.
567 GenericOutStream& putFloat64(double value);
568
569 /// Write to the stream supplied at construction the four-byte IEEE
570 /// single-precision floating-point number (in network byte order)
571 /// comprised of the most-significant four bytes of the specified
572 /// `value` (in host byte order), and return a reference to this stream.
573 /// If this stream is initially invalid, this operation has no effect.
574 /// Note that for non-conforming platforms, this operation may be lossy.
575 GenericOutStream& putFloat32(float value);
576
577 // *** string values ***
578
579 /// Write to the stream supplied at construction the length of the
580 /// specified `value` (see `putLength`) and an array of one-byte, two's
581 /// complement unsigned integers comprised of the least-significant one
582 /// byte of each character in the `value`, and return a reference to
583 /// this stream. If this stream is initially invalid, this operation
584 /// has no effect.
586
587 // *** arrays of integer values ***
588
589 /// Write to the stream supplied at construction the consecutive
590 /// eight-byte, two's complement integers (in network byte order)
591 /// comprised of the least-significant eight bytes of each of the
592 /// specified `numValues` leading entries in the specified `values` (in
593 /// host byte order), and return a reference to this stream. If this
594 /// stream is initially invalid, this operation has no effect. The
595 /// behavior is undefined unless `0 <= numValues` and `values` has
596 /// sufficient contents.
598 int numValues);
599
600 /// Write to the stream supplied at construction the consecutive
601 /// eight-byte, two's complement unsigned integers (in network byte
602 /// order) comprised of the least-significant eight bytes of each of the
603 /// specified `numValues` leading entries in the specified `values` (in
604 /// host byte order), and return a reference to this stream. If this
605 /// stream is initially invalid, this operation has no effect. The
606 /// behavior is undefined unless `0 <= numValues` and `values` has
607 /// sufficient contents.
609 int numValues);
610
611 /// Write to the stream supplied at construction the consecutive
612 /// seven-byte, two's complement integers (in network byte order)
613 /// comprised of the least-significant seven bytes of each of the
614 /// specified `numValues` leading entries in the specified `values` (in
615 /// host byte order), and return a reference to this stream. If this
616 /// stream is initially invalid, this operation has no effect. The
617 /// behavior is undefined unless `0 <= numValues` and `values` has
618 /// sufficient contents.
620 int numValues);
621
622 /// Write to the stream supplied at construction the consecutive
623 /// seven-byte, two's complement unsigned integers (in network byte
624 /// order) comprised of the least-significant seven bytes of each of the
625 /// specified `numValues` leading entries in the specified `values` (in
626 /// host byte order), and return a reference to this stream. If this
627 /// stream is initially invalid, this operation has no effect. The
628 /// behavior is undefined unless `0 <= numValues` and `values` has
629 /// sufficient contents.
631 int numValues);
632
633 /// Write to the stream supplied at construction the consecutive
634 /// six-byte, two's complement integers (in network byte order)
635 /// comprised of the least-significant six bytes of each of the
636 /// specified `numValues` leading entries in the specified `values` (in
637 /// host byte order), and return a reference to this stream. If this
638 /// stream is initially invalid, this operation has no effect. The
639 /// behavior is undefined unless `0 <= numValues` and `values` has
640 /// sufficient contents.
642 int numValues);
643
644 /// Write to the stream supplied at construction the consecutive
645 /// six-byte, two's complement unsigned integers (in network byte order)
646 /// comprised of the least-significant six bytes of each of the
647 /// specified `numValues` leading entries in the specified `values` (in
648 /// host byte order), and return a reference to this stream. If this
649 /// stream is initially invalid, this operation has no effect. The
650 /// behavior is undefined unless `0 <= numValues` and `values` has
651 /// sufficient contents.
653 int numValues);
654
655 /// Write to the stream supplied at construction the consecutive
656 /// five-byte, two's complement integers (in network byte order)
657 /// comprised of the least-significant five bytes of each of the
658 /// specified `numValues` leading entries in the specified `values` (in
659 /// host byte order), and return a reference to this stream. If this
660 /// stream is initially invalid, this operation has no effect. The
661 /// behavior is undefined unless `0 <= numValues` and `values` has
662 /// sufficient contents.
664 int numValues);
665
666 /// Write to the stream supplied at construction the consecutive
667 /// five-byte, two's complement unsigned integers (in network byte
668 /// order) comprised of the least-significant five bytes of each of the
669 /// specified `numValues` leading entries in the specified `values` (in
670 /// host byte order), and return a reference to this stream. If this
671 /// stream is initially invalid, this operation has no effect. The
672 /// behavior is undefined unless `0 <= numValues` and `values` has
673 /// sufficient contents.
675 int numValues);
676
677 /// Write to the stream supplied at construction the consecutive
678 /// four-byte, two's complement integers (in network byte order)
679 /// comprised of the least-significant four bytes of each of the
680 /// specified `numValues` leading entries in the specified `values` (in
681 /// host byte order), and return a reference to this stream. If this
682 /// stream is initially invalid, this operation has no effect. The
683 /// behavior is undefined unless `0 <= numValues` and `values` has
684 /// sufficient contents.
685 GenericOutStream& putArrayInt32(const int *values, int numValues);
686
687 /// Write to the stream supplied at construction the consecutive
688 /// four-byte, two's complement unsigned integers (in network byte
689 /// order) comprised of the least-significant four bytes of each of the
690 /// specified `numValues` leading entries in the specified `values` (in
691 /// host byte order), and return a reference to this stream. If this
692 /// stream is initially invalid, this operation has no effect. The
693 /// behavior is undefined unless `0 <= numValues` and `values` has
694 /// sufficient contents.
695 GenericOutStream& putArrayUint32(const unsigned int *values,
696 int numValues);
697
698 /// Write to the stream supplied at construction the consecutive
699 /// three-byte, two's complement integers (in network byte order)
700 /// comprised of the least-significant three bytes of each of the
701 /// specified `numValues` leading entries in the specified `values` (in
702 /// host byte order), and return a reference to this stream. If this
703 /// stream is initially invalid, this operation has no effect. The
704 /// behavior is undefined unless `0 <= numValues` and `values` has
705 /// sufficient contents.
706 GenericOutStream& putArrayInt24(const int *values, int numValues);
707
708 /// Write to the stream supplied at construction the consecutive
709 /// three-byte, two's complement unsigned integers (in network byte
710 /// order) comprised of the least-significant three bytes of each of the
711 /// specified `numValues` leading entries in the specified `values` (in
712 /// host byte order), and return a reference to this stream. If this
713 /// stream is initially invalid, this operation has no effect. The
714 /// behavior is undefined unless `0 <= numValues` and `values` has
715 /// sufficient contents.
716 GenericOutStream& putArrayUint24(const unsigned int *values,
717 int numValues);
718
719 /// Write to the stream supplied at construction the consecutive
720 /// two-byte, two's complement integers (in network byte order)
721 /// comprised of the least-significant two bytes of each of the
722 /// specified `numValues` leading entries in the specified `values` (in
723 /// host byte order), and return a reference to this stream. If this
724 /// stream is initially invalid, this operation has no effect. The
725 /// behavior is undefined unless `0 <= numValues` and `values` has
726 /// sufficient contents.
727 GenericOutStream& putArrayInt16(const short *values, int numValues);
728
729 /// Write to the stream supplied at construction the consecutive
730 /// two-byte, two's complement unsigned integers (in network byte order)
731 /// comprised of the least-significant two bytes of each of the
732 /// specified `numValues` leading entries in the specified `values` (in
733 /// host byte order), and return a reference to this stream. If this
734 /// stream is initially invalid, this operation has no effect. The
735 /// behavior is undefined unless `0 <= numValues` and `values` has
736 /// sufficient contents.
737 GenericOutStream& putArrayUint16(const unsigned short *values,
738 int numValues);
739
740 /// Write to the stream supplied at construction the consecutive
741 /// one-byte, two's complement integers comprised of the
742 /// least-significant one byte of each of the specified `numValues`
743 /// leading entries in the specified `values`, and return a reference to
744 /// this stream. If this stream is initially invalid, this operation
745 /// has no effect. The behavior is undefined unless `0 <= numValues`
746 /// and `values` has sufficient contents.
747 GenericOutStream& putArrayInt8(const char *values, int numValues);
748 GenericOutStream& putArrayInt8(const signed char *values, int numValues);
749
750 /// Write to the stream supplied at construction the consecutive
751 /// one-byte, two's complement unsigned integers comprised of the
752 /// least-significant one byte of each of the specified `numValues`
753 /// leading entries in the specified `values`, and return a reference to
754 /// this stream. If this stream is initially invalid, this operation
755 /// has no effect. The behavior is undefined unless `0 <= numValues`
756 /// and `values` has sufficient contents.
757 GenericOutStream& putArrayUint8(const char *values,
758 int numValues);
759 GenericOutStream& putArrayUint8(const unsigned char *values,
760 int numValues);
761
762 // *** arrays of floating-point values ***
763
764 /// Write to the stream supplied at construction the consecutive
765 /// eight-byte IEEE double-precision floating-point numbers (in network
766 /// byte order) comprised of the most-significant eight bytes of each of
767 /// the specified `numValues` leading entries in the specified `values`
768 /// (in host byte order), and return a reference to this stream. If
769 /// this stream is initially invalid, this operation has no effect. The
770 /// behavior is undefined unless `0 <= numValues` and `values` has
771 /// sufficient contents. Note that for non-conforming platforms, this
772 /// operation may be lossy.
773 GenericOutStream& putArrayFloat64(const double *values, int numValues);
774
775 /// Write to the stream supplied at construction the consecutive
776 /// four-byte IEEE single-precision floating-point numbers (in network
777 /// byte order) comprised of the most-significant four bytes of each of
778 /// the specified `numValues` leading entries in the specified `values`
779 /// (in host byte order), and return a reference to this stream. If
780 /// this stream is initially invalid, this operation has no effect. The
781 /// behavior is undefined unless `0 <= numValues` and `values` has
782 /// sufficient contents. Note that for non-conforming platforms, this
783 /// operation may be lossy.
784 GenericOutStream& putArrayFloat32(const float *values, int numValues);
785
786 // ACCESSORS
787
788 /// Return a non-zero value if this stream is valid, and 0 otherwise.
789 /// An invalid stream is a stream for which an output operation was
790 /// detected to have failed or `invalidate` was called.
791 operator const void *() const;
792
793 /// Return the `versionSelector` to be used with `operator<<` for BDEX
794 /// streaming as per the `bslx` package-level documentation.
795 int bdexVersionSelector() const;
796
797 /// Return `true` if this stream is valid, and `false` otherwise. An
798 /// invalid stream is a stream for which an output operation was
799 /// detected to have failed or `invalidate` was called.
800 bool isValid() const;
801};
802
803// FREE OPERATORS
804
805/// Write the specified `value` to the specified output `stream` following
806/// the requirements of the BDEX protocol (see the `bslx` package-level
807/// documentation), and return a reference to `stream`. The behavior is
808/// undefined unless `TYPE` is BDEX-compliant.
809template <class STREAMBUF, class TYPE>
811operator<<(GenericOutStream<STREAMBUF>& stream, const TYPE& value);
812
813// ============================================================================
814// INLINE DEFINITIONS
815// ============================================================================
816
817 // ----------------------
818 // class GenericOutStream
819 // ----------------------
820
821// PRIVATE MANIPULATORS
822template <class STREAMBUF>
823inline
825{
826 d_validFlag = true;
827}
828
829// CREATORS
830template <class STREAMBUF>
831inline
833 int versionSelector)
834: d_streamBuf(streamBuf)
835, d_versionSelector(versionSelector)
836, d_validFlag(true)
837{
838 BSLS_ASSERT_SAFE(streamBuf);
839}
840
841template <class STREAMBUF>
842inline
846
847// MANIPULATORS
848template <class STREAMBUF>
849inline
851{
852 if (isValid()) {
853 invalidate();
854 if (0 == d_streamBuf->pubsync()) {
855 validate();
856 }
857 }
858 return *this;
859}
860
861template <class STREAMBUF>
862inline
864{
865 d_validFlag = false;
866}
867
868template <class STREAMBUF>
869inline
872{
873 BSLS_ASSERT_SAFE(0 <= length);
874
875 if (length > 127) {
876 putInt32(length | (1 << 31));
877 }
878 else {
879 putInt8(length);
880 }
881 return *this;
882}
883
884template <class STREAMBUF>
885inline
888{
889 return putUint8(version);
890}
891
892 // *** scalar integer values ***
893
894template <class STREAMBUF>
895inline
898{
901 return *this; // RETURN
902 }
903
904 invalidate();
905
906#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
907 const char *rawBytes = reinterpret_cast<char *>(&value);
908 char bytes[k_SIZEOF_INT64];
909
910 bytes[0] = rawBytes[7];
911 bytes[1] = rawBytes[6];
912 bytes[2] = rawBytes[5];
913 bytes[3] = rawBytes[4];
914 bytes[4] = rawBytes[3];
915 bytes[5] = rawBytes[2];
916 bytes[6] = rawBytes[1];
917 bytes[7] = rawBytes[0];
918#else
919 const char *bytes =
920 reinterpret_cast<char *>(&value) + sizeof value - k_SIZEOF_INT64;
921#endif
922
923 if (k_SIZEOF_INT64 == d_streamBuf->sputn(bytes, k_SIZEOF_INT64)) {
924 validate();
925 }
926
927 return *this;
928}
929
930template <class STREAMBUF>
931inline
934{
935 return putInt64(static_cast<bsls::Types::Int64>(value));
936}
937
938template <class STREAMBUF>
939inline
942{
945 return *this; // RETURN
946 }
947
948 invalidate();
949
950#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
951 const char *rawBytes = reinterpret_cast<char *>(&value);
952 char bytes[k_SIZEOF_INT56];
953
954 bytes[0] = rawBytes[6];
955 bytes[1] = rawBytes[5];
956 bytes[2] = rawBytes[4];
957 bytes[3] = rawBytes[3];
958 bytes[4] = rawBytes[2];
959 bytes[5] = rawBytes[1];
960 bytes[6] = rawBytes[0];
961#else
962 const char *bytes =
963 reinterpret_cast<char *>(&value) + sizeof value - k_SIZEOF_INT56;
964#endif
965
966 if (k_SIZEOF_INT56 == d_streamBuf->sputn(bytes, k_SIZEOF_INT56)) {
967 validate();
968 }
969
970 return *this;
971}
972
973template <class STREAMBUF>
974inline
977{
978 return putInt56(static_cast<bsls::Types::Int64>(value));
979}
980
981template <class STREAMBUF>
982inline
985{
988 return *this; // RETURN
989 }
990
991 invalidate();
992
993#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
994 const char *rawBytes = reinterpret_cast<char *>(&value);
995 char bytes[k_SIZEOF_INT48];
996
997 bytes[0] = rawBytes[5];
998 bytes[1] = rawBytes[4];
999 bytes[2] = rawBytes[3];
1000 bytes[3] = rawBytes[2];
1001 bytes[4] = rawBytes[1];
1002 bytes[5] = rawBytes[0];
1003#else
1004 const char *bytes =
1005 reinterpret_cast<char *>(&value) + sizeof value - k_SIZEOF_INT48;
1006#endif
1007
1008 if (k_SIZEOF_INT48 == d_streamBuf->sputn(bytes, k_SIZEOF_INT48)) {
1009 validate();
1010 }
1011
1012 return *this;
1013}
1014
1015template <class STREAMBUF>
1016inline
1019{
1020 return putInt48(static_cast<bsls::Types::Int64>(value));
1021}
1022
1023template <class STREAMBUF>
1024inline
1027{
1028 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1030 return *this; // RETURN
1031 }
1032
1033 invalidate();
1034
1035#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1036 const char *rawBytes = reinterpret_cast<char *>(&value);
1037 char bytes[k_SIZEOF_INT40];
1038
1039 bytes[0] = rawBytes[4];
1040 bytes[1] = rawBytes[3];
1041 bytes[2] = rawBytes[2];
1042 bytes[3] = rawBytes[1];
1043 bytes[4] = rawBytes[0];
1044#else
1045 const char *bytes =
1046 reinterpret_cast<char *>(&value) + sizeof value - k_SIZEOF_INT40;
1047#endif
1048
1049 if (k_SIZEOF_INT40 == d_streamBuf->sputn(bytes, k_SIZEOF_INT40)) {
1050 validate();
1051 }
1052
1053 return *this;
1054}
1055
1056template <class STREAMBUF>
1057inline
1060{
1061 return putInt40(static_cast<bsls::Types::Int64>(value));
1062}
1063
1064template <class STREAMBUF>
1065inline
1068{
1069 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1071 return *this; // RETURN
1072 }
1073
1074 invalidate();
1075
1076#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1077 const char *rawBytes = reinterpret_cast<char *>(&value);
1078 char bytes[k_SIZEOF_INT32];
1079
1080 bytes[0] = rawBytes[3];
1081 bytes[1] = rawBytes[2];
1082 bytes[2] = rawBytes[1];
1083 bytes[3] = rawBytes[0];
1084#else
1085 const char *bytes =
1086 reinterpret_cast<char *>(&value) + sizeof value - k_SIZEOF_INT32;
1087#endif
1088
1089 if (k_SIZEOF_INT32 == d_streamBuf->sputn(bytes, k_SIZEOF_INT32)) {
1090 validate();
1091 }
1092
1093 return *this;
1094}
1095
1096template <class STREAMBUF>
1097inline
1100{
1101 return putInt32(static_cast<int>(value));
1102}
1103
1104template <class STREAMBUF>
1105inline
1108{
1109 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1111 return *this; // RETURN
1112 }
1113
1114 invalidate();
1115
1116#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1117 const char *rawBytes = reinterpret_cast<char *>(&value);
1118 char bytes[k_SIZEOF_INT24];
1119
1120 bytes[0] = rawBytes[2];
1121 bytes[1] = rawBytes[1];
1122 bytes[2] = rawBytes[0];
1123#else
1124 const char *bytes =
1125 reinterpret_cast<char *>(&value) + sizeof value - k_SIZEOF_INT24;
1126#endif
1127
1128 if (k_SIZEOF_INT24 == d_streamBuf->sputn(bytes, k_SIZEOF_INT24)) {
1129 validate();
1130 }
1131
1132 return *this;
1133}
1134
1135template <class STREAMBUF>
1136inline
1139{
1140 return putInt24(static_cast<int>(value));
1141}
1142
1143template <class STREAMBUF>
1144inline
1147{
1148 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1150 return *this; // RETURN
1151 }
1152
1153 invalidate();
1154
1155#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1156 const char *rawBytes = reinterpret_cast<char *>(&value);
1157 char bytes[k_SIZEOF_INT16];
1158
1159 bytes[0] = rawBytes[1];
1160 bytes[1] = rawBytes[0];
1161#else
1162 const char *bytes =
1163 reinterpret_cast<char *>(&value) + sizeof value - k_SIZEOF_INT16;
1164#endif
1165
1166 if (k_SIZEOF_INT16 == d_streamBuf->sputn(bytes, k_SIZEOF_INT16)) {
1167 validate();
1168 }
1169
1170 return *this;
1171}
1172
1173template <class STREAMBUF>
1174inline
1177{
1178 return putInt16(static_cast<int>(value));
1179}
1180
1181template <class STREAMBUF>
1182inline
1185{
1186 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1188 return *this; // RETURN
1189 }
1190
1191 invalidate();
1192
1193 if (STREAMBUF::traits_type::eof() !=
1194 d_streamBuf->sputc(static_cast<char>(value))) {
1195 validate();
1196 }
1197
1198 return *this;
1199}
1200
1201template <class STREAMBUF>
1202inline
1205{
1206 return putInt8(static_cast<int>(value));
1207}
1208
1209 // *** scalar floating-point values ***
1210
1211template <class STREAMBUF>
1212inline
1215{
1216 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1218 return *this; // RETURN
1219 }
1220
1221 invalidate();
1222
1223#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1224 const char *rawBytes = reinterpret_cast<char *>(&value);
1225 char bytes[k_SIZEOF_FLOAT64];
1226
1227 bytes[0] = rawBytes[sizeof value - 1];
1228 bytes[1] = rawBytes[sizeof value - 2];
1229 bytes[2] = rawBytes[sizeof value - 3];
1230 bytes[3] = rawBytes[sizeof value - 4];
1231 bytes[4] = rawBytes[sizeof value - 5];
1232 bytes[5] = rawBytes[sizeof value - 6];
1233 bytes[6] = rawBytes[sizeof value - 7];
1234 bytes[7] = rawBytes[sizeof value - 8];
1235#else
1236 const char *bytes = reinterpret_cast<char *>(&value);
1237#endif
1238
1239 if (k_SIZEOF_FLOAT64 == d_streamBuf->sputn(bytes, k_SIZEOF_FLOAT64)) {
1240 validate();
1241 }
1242
1243 return *this;
1244}
1245
1246template <class STREAMBUF>
1247inline
1250{
1251 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid())) {
1253 return *this; // RETURN
1254 }
1255
1256 invalidate();
1257
1258#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1259 const char *rawBytes = reinterpret_cast<char *>(&value);
1260 char bytes[k_SIZEOF_FLOAT32];
1261
1262 bytes[0] = rawBytes[sizeof value - 1];
1263 bytes[1] = rawBytes[sizeof value - 2];
1264 bytes[2] = rawBytes[sizeof value - 3];
1265 bytes[3] = rawBytes[sizeof value - 4];
1266#else
1267 const char *bytes = reinterpret_cast<char *>(&value);
1268#endif
1269
1270 if (k_SIZEOF_FLOAT32 == d_streamBuf->sputn(bytes, k_SIZEOF_FLOAT32)) {
1271 validate();
1272 }
1273
1274 return *this;
1275}
1276
1277 // *** string values ***
1278
1279template <class STREAMBUF>
1280inline
1283{
1284 putLength(static_cast<int>(value.length()));
1285 return putArrayUint8(value.data(), static_cast<int>(value.length()));
1286}
1287
1288 // *** arrays of integer values ***
1289
1290template <class STREAMBUF>
1293 int numValues)
1294{
1295 BSLS_ASSERT(values);
1296 BSLS_ASSERT(0 <= numValues);
1297
1298 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1300 return *this; // RETURN
1301 }
1302
1303 const bsls::Types::Int64 *end = values + numValues;
1304 for (; values != end; ++values) {
1305 putInt64(*values);
1306 }
1307
1308 return *this;
1309}
1310
1311template <class STREAMBUF>
1314 const bsls::Types::Uint64 *values,
1315 int numValues)
1316{
1317 BSLS_ASSERT(values);
1318 BSLS_ASSERT(0 <= numValues);
1319
1320 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1322 return *this; // RETURN
1323 }
1324
1325 const bsls::Types::Uint64 *end = values + numValues;
1326 for (; values != end; ++values) {
1327 putUint64(*values);
1328 }
1329
1330 return *this;
1331}
1332
1333template <class STREAMBUF>
1336 int numValues)
1337{
1338 BSLS_ASSERT(values);
1339 BSLS_ASSERT(0 <= numValues);
1340
1341 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1343 return *this; // RETURN
1344 }
1345
1346 const bsls::Types::Int64 *end = values + numValues;
1347 for (; values != end; ++values) {
1348 putInt56(*values);
1349 }
1350
1351 return *this;
1352}
1353
1354template <class STREAMBUF>
1357 const bsls::Types::Uint64 *values,
1358 int numValues)
1359{
1360 BSLS_ASSERT(values);
1361 BSLS_ASSERT(0 <= numValues);
1362
1363 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1365 return *this; // RETURN
1366 }
1367
1368 const bsls::Types::Uint64 *end = values + numValues;
1369 for (; values != end; ++values) {
1370 putUint56(*values);
1371 }
1372
1373 return *this;
1374}
1375
1376template <class STREAMBUF>
1379 int numValues)
1380{
1381 BSLS_ASSERT(values);
1382 BSLS_ASSERT(0 <= numValues);
1383
1384 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1386 return *this; // RETURN
1387 }
1388
1389 const bsls::Types::Int64 *end = values + numValues;
1390 for (; values != end; ++values) {
1391 putInt48(*values);
1392 }
1393
1394 return *this;
1395}
1396
1397template <class STREAMBUF>
1400 const bsls::Types::Uint64 *values,
1401 int numValues)
1402{
1403 BSLS_ASSERT(values);
1404 BSLS_ASSERT(0 <= numValues);
1405
1406 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1408 return *this; // RETURN
1409 }
1410
1411 const bsls::Types::Uint64 *end = values + numValues;
1412 for (; values != end; ++values) {
1413 putUint48(*values);
1414 }
1415
1416 return *this;
1417}
1418
1419template <class STREAMBUF>
1422 int numValues)
1423{
1424 BSLS_ASSERT(values);
1425 BSLS_ASSERT(0 <= numValues);
1426
1427 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1429 return *this; // RETURN
1430 }
1431
1432 const bsls::Types::Int64 *end = values + numValues;
1433 for (; values != end; ++values) {
1434 putInt40(*values);
1435 }
1436
1437 return *this;
1438}
1439
1440template <class STREAMBUF>
1443 const bsls::Types::Uint64 *values,
1444 int numValues)
1445{
1446 BSLS_ASSERT(values);
1447 BSLS_ASSERT(0 <= numValues);
1448
1449 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1451 return *this; // RETURN
1452 }
1453
1454 const bsls::Types::Uint64 *end = values + numValues;
1455 for (; values != end; ++values) {
1456 putUint40(*values);
1457 }
1458
1459 return *this;
1460}
1461
1462template <class STREAMBUF>
1464GenericOutStream<STREAMBUF>::putArrayInt32(const int *values, int numValues)
1465{
1466 BSLS_ASSERT(values);
1467 BSLS_ASSERT(0 <= numValues);
1468
1469 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1471 return *this; // RETURN
1472 }
1473
1474 const int *end = values + numValues;
1475 for (; values != end; ++values) {
1476 putInt32(*values);
1477 }
1478
1479 return *this;
1480}
1481
1482template <class STREAMBUF>
1485 int numValues)
1486{
1487 BSLS_ASSERT(values);
1488 BSLS_ASSERT(0 <= numValues);
1489
1490 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1492 return *this; // RETURN
1493 }
1494
1495 const unsigned int *end = values + numValues;
1496 for (; values != end; ++values) {
1497 putUint32(*values);
1498 }
1499
1500 return *this;
1501}
1502
1503template <class STREAMBUF>
1505GenericOutStream<STREAMBUF>::putArrayInt24(const int *values, int numValues)
1506{
1507 BSLS_ASSERT(values);
1508 BSLS_ASSERT(0 <= numValues);
1509
1510 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1512 return *this; // RETURN
1513 }
1514
1515 const int *end = values + numValues;
1516 for (; values != end; ++values) {
1517 putInt24(*values);
1518 }
1519
1520 return *this;
1521}
1522
1523template <class STREAMBUF>
1526 int numValues)
1527{
1528 BSLS_ASSERT(values);
1529 BSLS_ASSERT(0 <= numValues);
1530
1531 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1533 return *this; // RETURN
1534 }
1535
1536 const unsigned int *end = values + numValues;
1537 for (; values != end; ++values) {
1538 putUint24(*values);
1539 }
1540
1541 return *this;
1542}
1543
1544template <class STREAMBUF>
1546GenericOutStream<STREAMBUF>::putArrayInt16(const short *values, int numValues)
1547{
1548 BSLS_ASSERT(values);
1549 BSLS_ASSERT(0 <= numValues);
1550
1551 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1553 return *this; // RETURN
1554 }
1555
1556 const short *end = values + numValues;
1557 for (; values != end; ++values) {
1558 putInt16(*values);
1559 }
1560
1561 return *this;
1562}
1563
1564template <class STREAMBUF>
1567 int numValues)
1568{
1569 BSLS_ASSERT(values);
1570 BSLS_ASSERT(0 <= numValues);
1571
1572 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1574 return *this; // RETURN
1575 }
1576
1577 const unsigned short *end = values + numValues;
1578 for (; values != end; ++values) {
1579 putUint16(*values);
1580 }
1581
1582 return *this;
1583}
1584
1585template <class STREAMBUF>
1586inline
1588GenericOutStream<STREAMBUF>::putArrayInt8(const char *values, int numValues)
1589{
1590 BSLS_ASSERT_SAFE(values);
1591 BSLS_ASSERT_SAFE(0 <= numValues);
1592
1593 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1595 return *this; // RETURN
1596 }
1597
1598 invalidate();
1599
1600 if (numValues == d_streamBuf->sputn(values, numValues)) {
1601 validate();
1602 }
1603
1604 return *this;
1605}
1606
1607template <class STREAMBUF>
1608inline
1611 int numValues)
1612{
1613 BSLS_ASSERT_SAFE(values);
1614 BSLS_ASSERT_SAFE(0 <= numValues);
1615
1616 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1618 return *this; // RETURN
1619 }
1620
1621 invalidate();
1622
1623 if (numValues == d_streamBuf->sputn(reinterpret_cast<const char *>(values),
1624 numValues)) {
1625 validate();
1626 }
1627
1628 return *this;
1629}
1630
1631template <class STREAMBUF>
1632inline
1634GenericOutStream<STREAMBUF>::putArrayUint8(const char *values, int numValues)
1635{
1636 BSLS_ASSERT_SAFE(values);
1637 BSLS_ASSERT_SAFE(0 <= numValues);
1638
1639 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1641 return *this; // RETURN
1642 }
1643
1644 invalidate();
1645
1646 if (numValues == d_streamBuf->sputn(values, numValues)) {
1647 validate();
1648 }
1649
1650 return *this;
1651}
1652
1653template <class STREAMBUF>
1654inline
1657 int numValues)
1658{
1659 BSLS_ASSERT_SAFE(values);
1660 BSLS_ASSERT_SAFE(0 <= numValues);
1661
1662 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1664 return *this; // RETURN
1665 }
1666
1667 invalidate();
1668
1669 if (numValues == d_streamBuf->sputn(reinterpret_cast<const char *>(values),
1670 numValues)) {
1671 validate();
1672 }
1673
1674 return *this;
1675}
1676
1677 // *** arrays of floating-point values ***
1678
1679template <class STREAMBUF>
1682 int numValues)
1683{
1684 BSLS_ASSERT(values);
1685 BSLS_ASSERT(0 <= numValues);
1686
1687 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1689 return *this; // RETURN
1690 }
1691
1692 const double *end = values + numValues;
1693 for (; values != end; ++values) {
1694 putFloat64(*values);
1695 }
1696
1697 return *this;
1698}
1699
1700template <class STREAMBUF>
1703 int numValues)
1704{
1705 BSLS_ASSERT(values);
1706 BSLS_ASSERT(0 <= numValues);
1707
1708 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1710 return *this; // RETURN
1711 }
1712
1713 const float *end = values + numValues;
1714 for (; values != end; ++values) {
1715 putFloat32(*values);
1716 }
1717
1718 return *this;
1719}
1720
1721// ACCESSORS
1722template <class STREAMBUF>
1723inline
1725{
1726 return isValid() ? this : 0;
1727}
1728
1729template <class STREAMBUF>
1730inline
1732{
1733 return d_versionSelector;
1734}
1735
1736template <class STREAMBUF>
1737inline
1739{
1740 return d_validFlag;
1741}
1742
1743// FREE OPERATORS
1744template <class STREAMBUF, class TYPE>
1745inline
1747operator<<(GenericOutStream<STREAMBUF>& stream, const TYPE& value)
1748{
1749 return OutStreamFunctions::bdexStreamOut(stream, value);
1750}
1751
1752} // close package namespace
1753
1754
1755#endif
1756
1757// ----------------------------------------------------------------------------
1758// Copyright 2014 Bloomberg Finance L.P.
1759//
1760// Licensed under the Apache License, Version 2.0 (the "License");
1761// you may not use this file except in compliance with the License.
1762// You may obtain a copy of the License at
1763//
1764// http://www.apache.org/licenses/LICENSE-2.0
1765//
1766// Unless required by applicable law or agreed to in writing, software
1767// distributed under the License is distributed on an "AS IS" BASIS,
1768// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1769// See the License for the specific language governing permissions and
1770// limitations under the License.
1771// ----------------------------- END-OF-FILE ----------------------------------
1772
1773/** @} */
1774/** @} */
1775/** @} */
Definition bslstl_string.h:1281
size_type length() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6601
CHAR_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6477
Definition bslx_genericoutstream.h:363
GenericOutStream & putFloat32(float value)
Definition bslx_genericoutstream.h:1249
GenericOutStream & putInt32(int value)
Definition bslx_genericoutstream.h:1067
GenericOutStream & putInt56(bsls::Types::Int64 value)
Definition bslx_genericoutstream.h:941
GenericOutStream & putLength(int length)
Definition bslx_genericoutstream.h:871
GenericOutStream & putUint56(bsls::Types::Uint64 value)
Definition bslx_genericoutstream.h:976
GenericOutStream & putArrayInt64(const bsls::Types::Int64 *values, int numValues)
Definition bslx_genericoutstream.h:1292
GenericOutStream & putArrayInt16(const short *values, int numValues)
Definition bslx_genericoutstream.h:1546
GenericOutStream & putUint40(bsls::Types::Uint64 value)
Definition bslx_genericoutstream.h:1059
int bdexVersionSelector() const
Definition bslx_genericoutstream.h:1731
GenericOutStream & putArrayUint48(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_genericoutstream.h:1399
GenericOutStream & putArrayUint32(const unsigned int *values, int numValues)
Definition bslx_genericoutstream.h:1484
GenericOutStream & putUint64(bsls::Types::Uint64 value)
Definition bslx_genericoutstream.h:933
GenericOutStream & putArrayUint40(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_genericoutstream.h:1442
GenericOutStream & putInt64(bsls::Types::Int64 value)
Definition bslx_genericoutstream.h:897
GenericOutStream & putArrayInt48(const bsls::Types::Int64 *values, int numValues)
Definition bslx_genericoutstream.h:1378
GenericOutStream & putVersion(int version)
Definition bslx_genericoutstream.h:887
GenericOutStream & putUint16(unsigned int value)
Definition bslx_genericoutstream.h:1176
GenericOutStream & putArrayInt24(const int *values, int numValues)
Definition bslx_genericoutstream.h:1505
GenericOutStream & putInt16(int value)
Definition bslx_genericoutstream.h:1146
GenericOutStream & putArrayUint56(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_genericoutstream.h:1356
GenericOutStream & putString(const bsl::string &value)
Definition bslx_genericoutstream.h:1282
GenericOutStream & putInt24(int value)
Definition bslx_genericoutstream.h:1107
GenericOutStream & putInt8(int value)
Definition bslx_genericoutstream.h:1184
GenericOutStream & putInt40(bsls::Types::Int64 value)
Definition bslx_genericoutstream.h:1026
GenericOutStream & putUint24(unsigned int value)
Definition bslx_genericoutstream.h:1138
GenericOutStream & putArrayInt32(const int *values, int numValues)
Definition bslx_genericoutstream.h:1464
bool isValid() const
Definition bslx_genericoutstream.h:1738
GenericOutStream & putArrayFloat64(const double *values, int numValues)
Definition bslx_genericoutstream.h:1681
GenericOutStream & putInt48(bsls::Types::Int64 value)
Definition bslx_genericoutstream.h:984
GenericOutStream & putArrayUint16(const unsigned short *values, int numValues)
Definition bslx_genericoutstream.h:1566
void invalidate()
Definition bslx_genericoutstream.h:863
GenericOutStream & putArrayUint64(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_genericoutstream.h:1313
GenericOutStream & putArrayUint24(const unsigned int *values, int numValues)
Definition bslx_genericoutstream.h:1525
GenericOutStream & putFloat64(double value)
Definition bslx_genericoutstream.h:1214
~GenericOutStream()
Destroy this object.
Definition bslx_genericoutstream.h:843
GenericOutStream & flush()
Definition bslx_genericoutstream.h:850
GenericOutStream & putUint48(bsls::Types::Uint64 value)
Definition bslx_genericoutstream.h:1018
GenericOutStream & putArrayFloat32(const float *values, int numValues)
Definition bslx_genericoutstream.h:1702
GenericOutStream & putArrayInt8(const char *values, int numValues)
Definition bslx_genericoutstream.h:1588
GenericOutStream & putUint32(unsigned int value)
Definition bslx_genericoutstream.h:1099
GenericOutStream & putUint8(unsigned int value)
Definition bslx_genericoutstream.h:1204
GenericOutStream & putArrayInt56(const bsls::Types::Int64 *values, int numValues)
Definition bslx_genericoutstream.h:1335
GenericOutStream & putArrayInt40(const bsls::Types::Int64 *values, int numValues)
Definition bslx_genericoutstream.h:1421
GenericOutStream & putArrayUint8(const char *values, int numValues)
Definition bslx_genericoutstream.h:1634
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
STREAM & bdexStreamOut(STREAM &stream, const TYPE &value)
Definition bslx_outstreamfunctions.h:992
Definition bslx_byteinstream.h:377
bsl::ostream & operator<<(bsl::ostream &stream, const ByteInStream &object)
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132