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