BDE 4.39.x 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 private:
229 // NOT IMPLEMENTED
231 ByteOutStream& operator=(const ByteOutStream&);
232
233 private:
234 // PRIVATE MANIPULATORS
235
236 /// Put this output stream into a valid state. This function has no
237 /// effect if this stream is already valid.
238 void validate();
239
240 public:
241 // CREATORS
242
243 /// Create an empty output byte stream that will use the specified
244 /// (*compile*-time-defined) `versionSelector` as needed (see
245 /// {Versioning}). Optionally specify a `basicAllocator` used to supply
246 /// memory. If `basicAllocator` is 0, the currently installed default allocator is used.
247 ///
248 /// \note Note that the `versionSelector` is expected to
249 /// be formatted as "YYYYMMDD", a date representation.
250 explicit ByteOutStream(int versionSelector,
251 bslma::Allocator *basicAllocator = 0);
252
253 /// Create an empty output byte stream having an initial buffer capacity
254 /// of at least the specified `initialCapacity` (in bytes) and that will
255 /// use the specified (*compile*-time-defined) `versionSelector` as
256 /// needed (see {Versioning}). Optionally specify a `basicAllocator`
257 /// used to supply memory. If `basicAllocator` is 0, the currently installed default allocator is used.
258 ///
259 /// \note Note that the
260 /// `versionSelector` is expected to be formatted as "YYYYMMDD", a date
261 /// representation.
262 ByteOutStream(int versionSelector,
263 bsl::size_t initialCapacity,
264 bslma::Allocator *basicAllocator = 0);
265
266 /// Destroy this object.
268
269 // MANIPULATORS
270
271 /// Put this output stream in an invalid state. This function has no
272 /// effect if this stream is already invalid.
273 void invalidate();
274
275 /// If the specified `length` is less than 128, write to this stream the
276 /// one-byte integer comprised of the least-significant one byte of the
277 /// `length`; otherwise, write to this stream the four-byte, two's
278 /// complement integer (in network byte order) comprised of the
279 /// least-significant four bytes of the `length` (in host byte order)
280 /// with the most-significant bit set. Return a reference to this
281 /// stream. If this stream is initially invalid, this operation has no effect.
282 ///
283 /// \pre The behavior is undefined unless `0 <= length`.
285
286 /// Write to this stream the one-byte, two's complement unsigned integer
287 /// comprised of the least-significant one byte of the specified
288 /// `version`, and return a reference to this stream. If this stream is
289 /// initially invalid, this operation has no effect.
290 ByteOutStream& putVersion(int version);
291
292 /// Set the internal buffer size of this stream to be at least the
293 /// specified `newCapacity` (in bytes).
294 void reserveCapacity(bsl::size_t newCapacity);
295
296 /// Remove all content in this stream and validate this stream if it is
297 /// currently invalid.
298 void reset();
299
300 // *** scalar integer values ***
301
302 /// Write to this stream the eight-byte, two's complement integer (in
303 /// network byte order) comprised of the least-significant eight bytes
304 /// of the specified `value` (in host byte order), and return a
305 /// reference to this stream. If this stream is initially invalid, this
306 /// operation has no effect.
308
309 /// Write to this stream the eight-byte, two's complement unsigned
310 /// integer (in network byte order) comprised of the least-significant
311 /// eight bytes of the specified `value` (in host byte order), and
312 /// return a reference to this stream. If this stream is initially
313 /// invalid, this operation has no effect.
315
316 /// Write to this stream the seven-byte, two's complement integer (in
317 /// network byte order) comprised of the least-significant seven bytes
318 /// of the specified `value` (in host byte order), and return a
319 /// reference to this stream. If this stream is initially invalid, this
320 /// operation has no effect.
322
323 /// Write to this stream the seven-byte, two's complement unsigned
324 /// integer (in network byte order) comprised of the least-significant
325 /// seven bytes of the specified `value` (in host byte order), and
326 /// return a reference to this stream. If this stream is initially
327 /// invalid, this operation has no effect.
329
330 /// Write to this stream the six-byte, two's complement integer (in
331 /// network byte order) comprised of the least-significant six bytes of
332 /// the specified `value` (in host byte order), and return a reference
333 /// to this stream. If this stream is initially invalid, this operation
334 /// has no effect.
336
337 /// Write to this stream the six-byte, two's complement unsigned integer
338 /// (in network byte order) comprised of the least-significant six bytes
339 /// of the specified `value` (in host byte order), and return a
340 /// reference to this stream. If this stream is initially invalid, this
341 /// operation has no effect.
343
344 /// Write to this stream the five-byte, two's complement integer (in
345 /// network byte order) comprised of the least-significant five bytes of
346 /// the specified `value` (in host byte order), and return a reference
347 /// to this stream. If this stream is initially invalid, this operation
348 /// has no effect.
350
351 /// Write to this stream the five-byte, two's complement unsigned
352 /// integer (in network byte order) comprised of the least-significant
353 /// five bytes of the specified `value` (in host byte order), and return
354 /// a reference to this stream. If this stream is initially invalid,
355 /// this operation has no effect.
357
358 /// Write to this stream the four-byte, two's complement integer (in
359 /// network byte order) comprised of the least-significant four bytes of
360 /// the specified `value` (in host byte order), and return a reference
361 /// to this stream. If this stream is initially invalid, this operation
362 /// has no effect.
363 ByteOutStream& putInt32(int value);
364
365 /// Write to this stream the four-byte, two's complement unsigned
366 /// integer (in network byte order) comprised of the least-significant
367 /// four bytes of the specified `value` (in host byte order), and return
368 /// a reference to this stream. If this stream is initially invalid,
369 /// this operation has no effect.
370 ByteOutStream& putUint32(unsigned int value);
371
372 /// Write to this stream the three-byte, two's complement integer (in
373 /// network byte order) comprised of the least-significant three bytes
374 /// of the specified `value` (in host byte order), and return a
375 /// reference to this stream. If this stream is initially invalid, this
376 /// operation has no effect.
377 ByteOutStream& putInt24(int value);
378
379 /// Write to this stream the three-byte, two's complement unsigned
380 /// integer (in network byte order) comprised of the least-significant
381 /// three bytes of the specified `value` (in host byte order), and
382 /// return a reference to this stream. If this stream is initially
383 /// invalid, this operation has no effect.
384 ByteOutStream& putUint24(unsigned int value);
385
386 /// Write to this stream the two-byte, two's complement integer (in
387 /// network byte order) comprised of the least-significant two bytes of
388 /// the specified `value` (in host byte order), and return a reference
389 /// to this stream. If this stream is initially invalid, this operation
390 /// has no effect.
391 ByteOutStream& putInt16(int value);
392
393 /// Write to this stream the two-byte, two's complement unsigned integer
394 /// (in network byte order) comprised of the least-significant two bytes
395 /// of the specified `value` (in host byte order), and return a
396 /// reference to this stream. If this stream is initially invalid, this
397 /// operation has no effect.
398 ByteOutStream& putUint16(unsigned int value);
399
400 /// Write to this stream the one-byte, two's complement integer
401 /// comprised of the least-significant one byte of the specified
402 /// `value`, and return a reference to this stream. If this stream is
403 /// initially invalid, this operation has no effect.
404 ByteOutStream& putInt8(int value);
405
406 /// Write to this stream the one-byte, two's complement unsigned integer
407 /// comprised of the least-significant one byte of the specified
408 /// `value`, and return a reference to this stream. If this stream is
409 /// initially invalid, this operation has no effect.
410 ByteOutStream& putUint8(unsigned int value);
411
412 // *** scalar floating-point values ***
413
414 /// Write to this stream the eight-byte IEEE double-precision
415 /// floating-point number (in network byte order) comprised of the
416 /// most-significant eight bytes of the specified `value` (in host byte
417 /// order), and return a reference to this stream. If this stream is initially invalid, this operation has no effect.
418 ///
419 /// \note Note that for
420 /// non-conforming platforms, this operation may be lossy.
421 ByteOutStream& putFloat64(double value);
422
423 /// Write to this stream the four-byte IEEE single-precision
424 /// floating-point number (in network byte order) comprised of the
425 /// most-significant four bytes of the specified `value` (in host byte
426 /// order), and return a reference to this stream. If this stream is initially invalid, this operation has no effect.
427 ///
428 /// \note Note that for
429 /// non-conforming platforms, this operation may be lossy.
430 ByteOutStream& putFloat32(float value);
431
432 // *** string values ***
433
434 /// Write to this stream the length of the specified `value` (see
435 /// `putLength`) and an array of one-byte, two's complement unsigned
436 /// integers comprised of the least-significant one byte of each
437 /// character in the `value`, and return a reference to this stream. If
438 /// this stream is initially invalid, this operation has no effect.
440
441 // *** arrays of integer values ***
442
443 /// Write to this stream the consecutive eight-byte, two's complement
444 /// integers (in network byte order) comprised of the least-significant
445 /// eight bytes of each of the specified `numValues` leading entries in
446 /// the specified `values` (in host byte order), and return a reference
447 /// to this stream. If this stream is initially invalid, this operation has no effect.
448 ///
449 /// \pre The behavior is undefined unless `0 <= numValues`
450 /// and `values` has sufficient contents.
452 int numValues);
453
454 /// Write to this stream the consecutive eight-byte, two's complement
455 /// unsigned integers (in network byte order) comprised of the
456 /// least-significant eight bytes of each of the specified `numValues`
457 /// leading entries in the specified `values` (in host byte order), and
458 /// return a reference to this stream. If this stream is initially
459 /// invalid, this operation has no effect.
460 ///
461 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
463 int numValues);
464
465 /// Write to this stream the consecutive seven-byte, two's complement
466 /// integers (in network byte order) comprised of the least-significant
467 /// seven bytes of each of the specified `numValues` leading entries in
468 /// the specified `values` (in host byte order), and return a reference
469 /// to this stream. If this stream is initially invalid, this operation has no effect.
470 ///
471 /// \pre The behavior is undefined unless `0 <= numValues`
472 /// and `values` has sufficient contents.
474 int numValues);
475
476 /// Write to this stream the consecutive seven-byte, two's complement
477 /// unsigned integers (in network byte order) comprised of the
478 /// least-significant seven bytes of each of the specified `numValues`
479 /// leading entries in the specified `values` (in host byte order), and
480 /// return a reference to this stream. If this stream is initially
481 /// invalid, this operation has no effect.
482 ///
483 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
485 int numValues);
486
487 /// Write to this stream the consecutive six-byte, two's complement
488 /// integers (in network byte order) comprised of the least-significant
489 /// six bytes of each of the specified `numValues` leading entries in
490 /// the specified `values` (in host byte order), and return a reference
491 /// to this stream. If this stream is initially invalid, this operation has no effect.
492 ///
493 /// \pre The behavior is undefined unless `0 <= numValues`
494 /// and `values` has sufficient contents.
496 int numValues);
497
498 /// Write to this stream the consecutive six-byte, two's complement
499 /// unsigned integers (in network byte order) comprised of the
500 /// least-significant six bytes of each of the specified `numValues`
501 /// leading entries in the specified `values` (in host byte order), and
502 /// return a reference to this stream. If this stream is initially
503 /// invalid, this operation has no effect.
504 ///
505 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
507 int numValues);
508
509 /// Write to this stream the consecutive five-byte, two's complement
510 /// integers (in network byte order) comprised of the least-significant
511 /// five bytes of each of the specified `numValues` leading entries in
512 /// the specified `values` (in host byte order), and return a reference
513 /// to this stream. If this stream is initially invalid, this operation has no effect.
514 ///
515 /// \pre The behavior is undefined unless `0 <= numValues`
516 /// and `values` has sufficient contents.
518 int numValues);
519
520 /// Write to this stream the consecutive five-byte, two's complement
521 /// unsigned integers (in network byte order) comprised of the
522 /// least-significant five bytes of each of the specified `numValues`
523 /// leading entries in the specified `values` (in host byte order), and
524 /// return a reference to this stream. If this stream is initially
525 /// invalid, this operation has no effect.
526 ///
527 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
529 int numValues);
530
531 /// Write to this stream the consecutive four-byte, two's complement
532 /// integers (in network byte order) comprised of the least-significant
533 /// four bytes of each of the specified `numValues` leading entries in
534 /// the specified `values` (in host byte order), and return a reference
535 /// to this stream. If this stream is initially invalid, this operation has no effect.
536 ///
537 /// \pre The behavior is undefined unless `0 <= numValues`
538 /// and `values` has sufficient contents.
539 ByteOutStream& putArrayInt32(const int *values, int numValues);
540
541 /// Write to this stream the consecutive four-byte, two's complement
542 /// unsigned integers (in network byte order) comprised of the
543 /// least-significant four bytes of each of the specified `numValues`
544 /// leading entries in the specified `values` (in host byte order), and
545 /// return a reference to this stream. If this stream is initially
546 /// invalid, this operation has no effect.
547 ///
548 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
549 ByteOutStream& putArrayUint32(const unsigned int *values, int numValues);
550
551 /// Write to this stream the consecutive three-byte, two's complement
552 /// integers (in network byte order) comprised of the least-significant
553 /// three bytes of each of the specified `numValues` leading entries in
554 /// the specified `values` (in host byte order), and return a reference
555 /// to this stream. If this stream is initially invalid, this operation has no effect.
556 ///
557 /// \pre The behavior is undefined unless `0 <= numValues`
558 /// and `values` has sufficient contents.
559 ByteOutStream& putArrayInt24(const int *values, int numValues);
560
561 /// Write to this stream the consecutive three-byte, two's complement
562 /// unsigned integers (in network byte order) comprised of the
563 /// least-significant three bytes of each of the specified `numValues`
564 /// leading entries in the specified `values` (in host byte order), and
565 /// return a reference to this stream. If this stream is initially
566 /// invalid, this operation has no effect.
567 ///
568 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
569 ByteOutStream& putArrayUint24(const unsigned int *values, int numValues);
570
571 /// Write to this stream the consecutive two-byte, two's complement
572 /// integers (in network byte order) comprised of the least-significant
573 /// two bytes of each of the specified `numValues` leading entries in
574 /// the specified `values` (in host byte order), and return a reference
575 /// to this stream. If this stream is initially invalid, this operation has no effect.
576 ///
577 /// \pre The behavior is undefined unless `0 <= numValues`
578 /// and `values` has sufficient contents.
579 ByteOutStream& putArrayInt16(const short *values, int numValues);
580
581 /// Write to this stream the consecutive two-byte, two's complement
582 /// unsigned integers (in network byte order) comprised of the
583 /// least-significant two bytes of each of the specified `numValues`
584 /// leading entries in the specified `values` (in host byte order), and
585 /// return a reference to this stream. If this stream is initially
586 /// invalid, this operation has no effect.
587 ///
588 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
589 ByteOutStream& putArrayUint16(const unsigned short *values, int numValues);
590
591 /// Write to this stream the consecutive one-byte, two's complement
592 /// integers comprised of the least-significant one byte of each of the
593 /// specified `numValues` leading entries in the specified `values`, and
594 /// return a reference to this stream. If this stream is initially
595 /// invalid, this operation has no effect.
596 ///
597 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
598 ByteOutStream& putArrayInt8(const char *values, int numValues);
599 ByteOutStream& putArrayInt8(const signed char *values, int numValues);
600
601 /// Write to this stream the consecutive one-byte, two's complement
602 /// unsigned integers comprised of the least-significant one byte of
603 /// each of the specified `numValues` leading entries in the specified
604 /// `values`, and return a reference to this stream. If this stream is
605 /// initially invalid, this operation has no effect.
606 ///
607 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient
608 /// contents.
609 ByteOutStream& putArrayUint8(const char *values, int numValues);
610 ByteOutStream& putArrayUint8(const unsigned char *values, int numValues);
611
612 // *** arrays of floating-point values ***
613
614 /// Write to this stream the consecutive eight-byte IEEE
615 /// double-precision floating-point numbers (in network byte order)
616 /// comprised of the most-significant eight bytes of each of the
617 /// specified `numValues` leading entries in the specified `values` (in
618 /// host byte order), and return a reference to this stream. If this
619 /// stream is initially invalid, this operation has no effect.
620 ///
621 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
622 ///
623 /// \note Note that for non-conforming platforms, this
624 /// operation may be lossy.
625 ByteOutStream& putArrayFloat64(const double *values, int numValues);
626
627 /// Write to this stream the consecutive four-byte IEEE single-precision
628 /// floating-point numbers (in network byte order) comprised of the
629 /// most-significant four bytes of each of the specified `numValues`
630 /// leading entries in the specified `values` (in host byte order), and
631 /// return a reference to this stream. If this stream is initially
632 /// invalid, this operation has no effect.
633 ///
634 /// \pre The behavior is undefined unless `0 <= numValues` and `values` has sufficient contents.
635 ///
636 /// \note Note that for non-conforming platforms, this operation may be lossy.
637 ByteOutStream& putArrayFloat32(const float *values, int numValues);
638
639 // ACCESSORS
640
641 /// Return a non-zero value if this stream is valid, and 0 otherwise.
642 /// An invalid stream is a stream for which an output operation was
643 /// detected to have failed or `invalidate` was called.
644 operator const void *() const;
645
646 /// Return the `versionSelector` to be used with `operator<<` for BDEX
647 /// streaming as per the `bslx` package-level documentation.
648 int bdexVersionSelector() const;
649
650 /// Return the address of the contiguous, non-modifiable internal memory
651 /// buffer of this stream. The address will remain valid as long as
652 /// this stream is not destroyed or modified. The behavior of accessing
653 /// elements outside the range `[ data() .. data() + (length() - 1) ]`
654 /// is undefined.
655 const char *data() const;
656
657 /// Return `true` if this stream is valid, and `false` otherwise. An
658 /// invalid stream is a stream for which an output operation was
659 /// detected to have failed or `invalidate` was called.
660 bool isValid() const;
661
662 /// Return the number of bytes in this stream.
663 bsl::size_t length() const;
664};
665
666// FREE OPERATORS
667
668/// Write the specified `object` to the specified output `stream` in some
669/// reasonable (multi-line) format, and return a reference to `stream`.
670bsl::ostream& operator<<(bsl::ostream& stream,
671 const ByteOutStream& object);
672
673/// Write the specified `value` to the specified output `stream` following
674/// the requirements of the BDEX protocol (see the `bslx` package-level
675/// documentation), and return a reference to `stream`.
676///
677/// \pre The behavior is undefined unless `TYPE` is BDEX-compliant.
678template <class TYPE>
679ByteOutStream& operator<<(ByteOutStream& stream, const TYPE& value);
680
681// ============================================================================
682// INLINE DEFINITIONS
683// ============================================================================
684
685 // -------------------
686 // class ByteOutStream
687 // -------------------
688
689// PRIVATE MANIPULATORS
690inline
691void ByteOutStream::validate()
692{
693 d_validFlag = true;
694}
695
696// CREATORS
697inline
698ByteOutStream::ByteOutStream(int versionSelector,
699 bslma::Allocator *basicAllocator)
700: d_buffer(basicAllocator)
701, d_versionSelector(versionSelector)
702, d_validFlag(true)
703{
704}
705
706inline
707ByteOutStream::ByteOutStream(int versionSelector,
708 bsl::size_t initialCapacity,
709 bslma::Allocator *basicAllocator)
710: d_buffer(basicAllocator)
711, d_versionSelector(versionSelector)
712, d_validFlag(true)
713{
714 d_buffer.reserve(initialCapacity);
715}
716
717inline
721
722// MANIPULATORS
723inline
725{
726 d_validFlag = false;
727}
728
729inline
731{
733
734 if (length > 127) {
735 putInt32(length | (1 << 31));
736 } else {
738 }
739 return *this;
740}
741
742inline
744{
745 return putUint8(version);
746}
747
748inline
749void ByteOutStream::reserveCapacity(bsl::size_t newCapacity)
750{
751 d_buffer.reserve(newCapacity);
752}
753
754inline
756{
757 d_buffer.clear();
758 validate();
759}
760
761 // *** scalar integer values ***
762
763inline
765{
768 return *this; // RETURN
769 }
770
771 // Resize the buffer to have sufficient capacity with care to ensure this
772 // stream is invalidated if an exception is thrown.
773
774 const bsl::size_t n = d_buffer.size();
775 invalidate();
777 validate();
778
779 // Write to the buffer the specified 'value'.
780
781 MarshallingUtil::putInt64(d_buffer.data() + n, value);
782
783 return *this;
784}
785
786inline
791
792inline
794{
797 return *this; // RETURN
798 }
799
800 // Resize the buffer to have sufficient capacity with care to ensure this
801 // stream is invalidated if an exception is thrown.
802
803 const bsl::size_t n = d_buffer.size();
804 invalidate();
806 validate();
807
808 // Write to the buffer the specified 'value'.
809
810 MarshallingUtil::putInt56(d_buffer.data() + n, value);
811
812 return *this;
813}
814
815inline
820
821inline
823{
826 return *this; // RETURN
827 }
828
829 // Resize the buffer to have sufficient capacity with care to ensure this
830 // stream is invalidated if an exception is thrown.
831
832 const bsl::size_t n = d_buffer.size();
833 invalidate();
835 validate();
836
837 // Write to the buffer the specified 'value'.
838
839 MarshallingUtil::putInt48(d_buffer.data() + n, value);
840
841 return *this;
842}
843
844inline
849
850inline
852{
855 return *this; // RETURN
856 }
857
858 // Resize the buffer to have sufficient capacity with care to ensure this
859 // stream is invalidated if an exception is thrown.
860
861 const bsl::size_t n = d_buffer.size();
862 invalidate();
864 validate();
865
866 // Write to the buffer the specified 'value'.
867
868 MarshallingUtil::putInt40(d_buffer.data() + n, value);
869
870 return *this;
871}
872
873inline
878
879inline
881{
884 return *this; // RETURN
885 }
886
887 // Resize the buffer to have sufficient capacity with care to ensure this
888 // stream is invalidated if an exception is thrown.
889
890 const bsl::size_t n = d_buffer.size();
891 invalidate();
893 validate();
894
895 // Write to the buffer the specified 'value'.
896
897 MarshallingUtil::putInt32(d_buffer.data() + n, value);
898
899 return *this;
900}
901
902inline
904{
905 return putInt32(static_cast<int>(value));
906}
907
908inline
910{
913 return *this; // RETURN
914 }
915
916 // Resize the buffer to have sufficient capacity with care to ensure this
917 // stream is invalidated if an exception is thrown.
918
919 const bsl::size_t n = d_buffer.size();
920 invalidate();
922 validate();
923
924 // Write to the buffer the specified 'value'.
925
926 MarshallingUtil::putInt24(d_buffer.data() + n, value);
927
928 return *this;
929}
930
931inline
933{
934 return putInt24(static_cast<int>(value));
935}
936
937inline
939{
942 return *this; // RETURN
943 }
944
945 // Resize the buffer to have sufficient capacity with care to ensure this
946 // stream is invalidated if an exception is thrown.
947
948 const bsl::size_t n = d_buffer.size();
949 invalidate();
951 validate();
952
953 // Write to the buffer the specified 'value'.
954
955 MarshallingUtil::putInt16(d_buffer.data() + n, value);
956
957 return *this;
958}
959
960inline
962{
963 return putInt16(static_cast<int>(value));
964}
965
966inline
968{
971 return *this; // RETURN
972 }
973
974 // Resize the buffer to have sufficient capacity with care to ensure this
975 // stream is invalidated if an exception is thrown.
976
977 const bsl::size_t n = d_buffer.size();
978 invalidate();
980 validate();
981
982 // Write to the buffer the specified 'value'.
983
984 MarshallingUtil::putInt8(d_buffer.data() + n, value);
985
986 return *this;
987}
988
989inline
991{
992 return putInt8(static_cast<int>(value));
993}
994
995 // *** scalar floating-point values ***
996
997inline
999{
1002 return *this; // RETURN
1003 }
1004
1005 // Resize the buffer to have sufficient capacity with care to ensure this
1006 // stream is invalidated if an exception is thrown.
1007
1008 const bsl::size_t n = d_buffer.size();
1009 invalidate();
1011 validate();
1012
1013 // Write to the buffer the specified 'value'.
1014
1015 MarshallingUtil::putFloat64(d_buffer.data() + n, value);
1016
1017 return *this;
1018}
1019
1020inline
1022{
1025 return *this; // RETURN
1026 }
1027
1028 // Resize the buffer to have sufficient capacity with care to ensure this
1029 // stream is invalidated if an exception is thrown.
1030
1031 const bsl::size_t n = d_buffer.size();
1032 invalidate();
1034 validate();
1035
1036 // Write to the buffer the specified 'value'.
1037
1038 MarshallingUtil::putFloat32(d_buffer.data() + n, value);
1039
1040 return *this;
1041}
1042
1043 // *** arrays of integer values ***
1044
1045inline
1047 const bsls::Types::Int64 *values,
1048 int numValues)
1049{
1050 BSLS_ASSERT_SAFE(values);
1051 BSLS_ASSERT_SAFE(0 <= numValues);
1052
1053 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1055 return *this; // RETURN
1056 }
1057
1058 // Resize the buffer to have sufficient capacity with care to ensure this
1059 // stream is invalidated if an exception is thrown.
1060
1061 const bsl::size_t n = d_buffer.size();
1062 invalidate();
1063 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT64);
1064 validate();
1065
1066 // Write to the buffer the specified 'value'.
1067
1068 MarshallingUtil::putArrayInt64(d_buffer.data() + n, values, numValues);
1069
1070 return *this;
1071}
1072
1073inline
1075 const bsls::Types::Uint64 *values,
1076 int numValues)
1077{
1078 BSLS_ASSERT_SAFE(values);
1079 BSLS_ASSERT_SAFE(0 <= numValues);
1080
1081 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1083 return *this; // RETURN
1084 }
1085
1086 // Resize the buffer to have sufficient capacity with care to ensure this
1087 // stream is invalidated if an exception is thrown.
1088
1089 const bsl::size_t n = d_buffer.size();
1090 invalidate();
1091 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT64);
1092 validate();
1093
1094 // Write to the buffer the specified 'value'.
1095
1096 MarshallingUtil::putArrayInt64(d_buffer.data() + n, values, numValues);
1097
1098 return *this;
1099}
1100
1101inline
1103 const bsls::Types::Int64 *values,
1104 int numValues)
1105{
1106 BSLS_ASSERT_SAFE(values);
1107 BSLS_ASSERT_SAFE(0 <= numValues);
1108
1109 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1111 return *this; // RETURN
1112 }
1113
1114 // Resize the buffer to have sufficient capacity with care to ensure this
1115 // stream is invalidated if an exception is thrown.
1116
1117 const bsl::size_t n = d_buffer.size();
1118 invalidate();
1119 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT56);
1120 validate();
1121
1122 // Write to the buffer the specified 'value'.
1123
1124 MarshallingUtil::putArrayInt56(d_buffer.data() + n, values, numValues);
1125
1126 return *this;
1127}
1128
1129inline
1131 const bsls::Types::Uint64 *values,
1132 int numValues)
1133{
1134 BSLS_ASSERT_SAFE(values);
1135 BSLS_ASSERT_SAFE(0 <= numValues);
1136
1137 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1139 return *this; // RETURN
1140 }
1141
1142 // Resize the buffer to have sufficient capacity with care to ensure this
1143 // stream is invalidated if an exception is thrown.
1144
1145 const bsl::size_t n = d_buffer.size();
1146 invalidate();
1147 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT56);
1148 validate();
1149
1150 // Write to the buffer the specified 'value'.
1151
1152 MarshallingUtil::putArrayInt56(d_buffer.data() + n, values, numValues);
1153
1154 return *this;
1155}
1156
1157inline
1159 const bsls::Types::Int64 *values,
1160 int numValues)
1161{
1162 BSLS_ASSERT_SAFE(values);
1163 BSLS_ASSERT_SAFE(0 <= numValues);
1164
1165 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1167 return *this; // RETURN
1168 }
1169
1170 // Resize the buffer to have sufficient capacity with care to ensure this
1171 // stream is invalidated if an exception is thrown.
1172
1173 const bsl::size_t n = d_buffer.size();
1174 invalidate();
1175 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT48);
1176 validate();
1177
1178 // Write to the buffer the specified 'value'.
1179
1180 MarshallingUtil::putArrayInt48(d_buffer.data() + n, values, numValues);
1181
1182 return *this;
1183}
1184
1185inline
1187 const bsls::Types::Uint64 *values,
1188 int numValues)
1189{
1190 BSLS_ASSERT_SAFE(values);
1191 BSLS_ASSERT_SAFE(0 <= numValues);
1192
1193 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1195 return *this; // RETURN
1196 }
1197
1198 // Resize the buffer to have sufficient capacity with care to ensure this
1199 // stream is invalidated if an exception is thrown.
1200
1201 const bsl::size_t n = d_buffer.size();
1202 invalidate();
1203 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT48);
1204 validate();
1205
1206 // Write to the buffer the specified 'value'.
1207
1208 MarshallingUtil::putArrayInt48(d_buffer.data() + n, values, numValues);
1209
1210 return *this;
1211}
1212
1213inline
1215 const bsls::Types::Int64 *values,
1216 int numValues)
1217{
1218 BSLS_ASSERT_SAFE(values);
1219 BSLS_ASSERT_SAFE(0 <= numValues);
1220
1221 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1223 return *this; // RETURN
1224 }
1225
1226 // Resize the buffer to have sufficient capacity with care to ensure this
1227 // stream is invalidated if an exception is thrown.
1228
1229 const bsl::size_t n = d_buffer.size();
1230 invalidate();
1231 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT40);
1232 validate();
1233
1234 // Write to the buffer the specified 'value'.
1235
1236 MarshallingUtil::putArrayInt40(d_buffer.data() + n, values, numValues);
1237
1238 return *this;
1239}
1240
1241inline
1243 const bsls::Types::Uint64 *values,
1244 int numValues)
1245{
1246 BSLS_ASSERT_SAFE(values);
1247 BSLS_ASSERT_SAFE(0 <= numValues);
1248
1249 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1251 return *this; // RETURN
1252 }
1253
1254 // Resize the buffer to have sufficient capacity with care to ensure this
1255 // stream is invalidated if an exception is thrown.
1256
1257 const bsl::size_t n = d_buffer.size();
1258 invalidate();
1259 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT40);
1260 validate();
1261
1262 // Write to the buffer the specified 'value'.
1263
1264 MarshallingUtil::putArrayInt40(d_buffer.data() + n, values, numValues);
1265
1266 return *this;
1267}
1268
1269inline
1270ByteOutStream& ByteOutStream::putArrayInt32(const int *values, 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
1297 int numValues)
1298{
1299 BSLS_ASSERT_SAFE(values);
1300 BSLS_ASSERT_SAFE(0 <= numValues);
1301
1302 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1304 return *this; // RETURN
1305 }
1306
1307 // Resize the buffer to have sufficient capacity with care to ensure this
1308 // stream is invalidated if an exception is thrown.
1309
1310 const bsl::size_t n = d_buffer.size();
1311 invalidate();
1312 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT32);
1313 validate();
1314
1315 // Write to the buffer the specified 'value'.
1316
1317 MarshallingUtil::putArrayInt32(d_buffer.data() + n, values, numValues);
1318
1319 return *this;
1320}
1321
1322inline
1323ByteOutStream& ByteOutStream::putArrayInt24(const int *values, 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
1350 int numValues)
1351{
1352 BSLS_ASSERT_SAFE(values);
1353 BSLS_ASSERT_SAFE(0 <= numValues);
1354
1355 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1357 return *this; // RETURN
1358 }
1359
1360 // Resize the buffer to have sufficient capacity with care to ensure this
1361 // stream is invalidated if an exception is thrown.
1362
1363 const bsl::size_t n = d_buffer.size();
1364 invalidate();
1365 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT24);
1366 validate();
1367
1368 // Write to the buffer the specified 'value'.
1369
1370 MarshallingUtil::putArrayInt24(d_buffer.data() + n, values, numValues);
1371
1372 return *this;
1373}
1374
1375inline
1376ByteOutStream& ByteOutStream::putArrayInt16(const short *values, 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::putArrayUint16(const unsigned short *values,
1403 int numValues)
1404{
1405 BSLS_ASSERT_SAFE(values);
1406 BSLS_ASSERT_SAFE(0 <= numValues);
1407
1408 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1410 return *this; // RETURN
1411 }
1412
1413 // Resize the buffer to have sufficient capacity with care to ensure this
1414 // stream is invalidated if an exception is thrown.
1415
1416 const bsl::size_t n = d_buffer.size();
1417 invalidate();
1418 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT16);
1419 validate();
1420
1421 // Write to the buffer the specified 'value'.
1422
1423 MarshallingUtil::putArrayInt16(d_buffer.data() + n, values, numValues);
1424
1425 return *this;
1426}
1427
1428inline
1429ByteOutStream& ByteOutStream::putArrayInt8(const char *values, 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
1456 int numValues)
1457{
1458 BSLS_ASSERT_SAFE(values);
1459 BSLS_ASSERT_SAFE(0 <= numValues);
1460
1461 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1463 return *this; // RETURN
1464 }
1465
1466 // Resize the buffer to have sufficient capacity with care to ensure this
1467 // stream is invalidated if an exception is thrown.
1468
1469 const bsl::size_t n = d_buffer.size();
1470 invalidate();
1471 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT8);
1472 validate();
1473
1474 // Write to the buffer the specified 'value'.
1475
1476 MarshallingUtil::putArrayInt8(d_buffer.data() + n, values, numValues);
1477
1478 return *this;
1479}
1480
1481inline
1482ByteOutStream& ByteOutStream::putArrayUint8(const char *values, 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
1507inline
1508ByteOutStream& ByteOutStream::putArrayUint8(const unsigned char *values,
1509 int numValues)
1510{
1511 BSLS_ASSERT_SAFE(values);
1512 BSLS_ASSERT_SAFE(0 <= numValues);
1513
1514 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1516 return *this; // RETURN
1517 }
1518
1519 // Resize the buffer to have sufficient capacity with care to ensure this
1520 // stream is invalidated if an exception is thrown.
1521
1522 const bsl::size_t n = d_buffer.size();
1523 invalidate();
1524 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_INT8);
1525 validate();
1526
1527 // Write to the buffer the specified 'value'.
1528
1529 MarshallingUtil::putArrayInt8(d_buffer.data() + n, values, numValues);
1530
1531 return *this;
1532}
1533
1534 // *** arrays of floating-point values ***
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_FLOAT64);
1554 validate();
1555
1556 // Write to the buffer the specified 'value'.
1557
1558 MarshallingUtil::putArrayFloat64(d_buffer.data() + n, values, numValues);
1559
1560 return *this;
1561}
1562
1563inline
1565 int numValues)
1566{
1567 BSLS_ASSERT_SAFE(values);
1568 BSLS_ASSERT_SAFE(0 <= numValues);
1569
1570 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!isValid() || 0 == numValues)) {
1572 return *this; // RETURN
1573 }
1574
1575 // Resize the buffer to have sufficient capacity with care to ensure this
1576 // stream is invalidated if an exception is thrown.
1577
1578 const bsl::size_t n = d_buffer.size();
1579 invalidate();
1580 d_buffer.resize(n + numValues * MarshallingUtil::k_SIZEOF_FLOAT32);
1581 validate();
1582
1583 // Write to the buffer the specified 'value'.
1584
1585 MarshallingUtil::putArrayFloat32(d_buffer.data() + n, values, numValues);
1586
1587 return *this;
1588}
1589
1590// ACCESSORS
1591inline
1592ByteOutStream::operator const void *() const
1593{
1594 return isValid() ? this : 0;
1595}
1596
1597inline
1599{
1600 return d_versionSelector;
1601}
1602
1603inline
1604const char *ByteOutStream::data() const
1605{
1606 return d_buffer.begin();
1607}
1608
1609inline
1611{
1612 return d_validFlag;
1613}
1614
1615inline
1616bsl::size_t ByteOutStream::length() const
1617{
1618 return d_buffer.size();
1619}
1620
1621// FREE OPERATORS
1622template <class TYPE>
1623inline
1624ByteOutStream& operator<<(ByteOutStream& stream, const TYPE& value)
1625{
1626 return OutStreamFunctions::bdexStreamOut(stream, value);
1627}
1628
1629} // close package namespace
1630
1631
1632// TRAITS
1633
1634namespace bslma {
1635
1636template <>
1637struct UsesBslmaAllocator<bslx::ByteOutStream> : bsl::true_type {};
1638
1639} // close namespace bslma
1640
1641
1642#endif
1643
1644// ----------------------------------------------------------------------------
1645// Copyright 2014 Bloomberg Finance L.P.
1646//
1647// Licensed under the Apache License, Version 2.0 (the "License");
1648// you may not use this file except in compliance with the License.
1649// You may obtain a copy of the License at
1650//
1651// http://www.apache.org/licenses/LICENSE-2.0
1652//
1653// Unless required by applicable law or agreed to in writing, software
1654// distributed under the License is distributed on an "AS IS" BASIS,
1655// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1656// See the License for the specific language governing permissions and
1657// limitations under the License.
1658// ----------------------------- END-OF-FILE ----------------------------------
1659
1660/** @} */
1661/** @} */
1662/** @} */
Definition bslstl_string.h:1252
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:3019
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2866
VALUE_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2942
Definition bslstl_vector.h:1120
void reserve(size_type newCapacity)
Definition bslstl_vector.h:4263
void swap(vector &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:1938
void resize(size_type newSize)
Definition bslstl_vector.h:4189
Definition bslma_allocator.h:545
Definition bslx_byteoutstream.h:212
ByteOutStream & putUint8(unsigned int value)
Definition bslx_byteoutstream.h:990
ByteOutStream & putArrayInt56(const bsls::Types::Int64 *values, int numValues)
Definition bslx_byteoutstream.h:1102
ByteOutStream & putUint64(bsls::Types::Uint64 value)
Definition bslx_byteoutstream.h:787
ByteOutStream & putArrayUint8(const char *values, int numValues)
Definition bslx_byteoutstream.h:1482
ByteOutStream & putArrayInt8(const char *values, int numValues)
Definition bslx_byteoutstream.h:1429
ByteOutStream & putArrayUint32(const unsigned int *values, int numValues)
Definition bslx_byteoutstream.h:1296
ByteOutStream & putUint48(bsls::Types::Uint64 value)
Definition bslx_byteoutstream.h:845
ByteOutStream & putVersion(int version)
Definition bslx_byteoutstream.h:743
ByteOutStream & putUint40(bsls::Types::Uint64 value)
Definition bslx_byteoutstream.h:874
ByteOutStream & putInt24(int value)
Definition bslx_byteoutstream.h:909
ByteOutStream & putArrayInt16(const short *values, int numValues)
Definition bslx_byteoutstream.h:1376
~ByteOutStream()
Destroy this object.
Definition bslx_byteoutstream.h:718
void invalidate()
Definition bslx_byteoutstream.h:724
ByteOutStream & putArrayUint64(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_byteoutstream.h:1074
ByteOutStream & putInt56(bsls::Types::Int64 value)
Definition bslx_byteoutstream.h:793
bool isValid() const
Definition bslx_byteoutstream.h:1610
ByteOutStream & putInt48(bsls::Types::Int64 value)
Definition bslx_byteoutstream.h:822
ByteOutStream & putInt8(int value)
Definition bslx_byteoutstream.h:967
ByteOutStream & putArrayUint40(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_byteoutstream.h:1242
ByteOutStream & putArrayUint24(const unsigned int *values, int numValues)
Definition bslx_byteoutstream.h:1349
ByteOutStream & putArrayUint16(const unsigned short *values, int numValues)
Definition bslx_byteoutstream.h:1402
ByteOutStream & putArrayInt24(const int *values, int numValues)
Definition bslx_byteoutstream.h:1323
void reserveCapacity(bsl::size_t newCapacity)
Definition bslx_byteoutstream.h:749
ByteOutStream & putArrayInt32(const int *values, int numValues)
Definition bslx_byteoutstream.h:1270
ByteOutStream & putUint16(unsigned int value)
Definition bslx_byteoutstream.h:961
bsl::size_t length() const
Return the number of bytes in this stream.
Definition bslx_byteoutstream.h:1616
friend bsl::ostream & operator<<(bsl::ostream &, const ByteOutStream &)
ByteOutStream & putInt40(bsls::Types::Int64 value)
Definition bslx_byteoutstream.h:851
ByteOutStream & putArrayInt48(const bsls::Types::Int64 *values, int numValues)
Definition bslx_byteoutstream.h:1158
ByteOutStream & putArrayFloat32(const float *values, int numValues)
Definition bslx_byteoutstream.h:1564
ByteOutStream & putInt32(int value)
Definition bslx_byteoutstream.h:880
ByteOutStream & putLength(int length)
Definition bslx_byteoutstream.h:730
ByteOutStream & putString(const bsl::string &value)
ByteOutStream & putArrayUint56(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_byteoutstream.h:1130
ByteOutStream & putFloat32(float value)
Definition bslx_byteoutstream.h:1021
const char * data() const
Definition bslx_byteoutstream.h:1604
ByteOutStream & putUint24(unsigned int value)
Definition bslx_byteoutstream.h:932
ByteOutStream & putUint32(unsigned int value)
Definition bslx_byteoutstream.h:903
ByteOutStream & putArrayUint48(const bsls::Types::Uint64 *values, int numValues)
Definition bslx_byteoutstream.h:1186
int bdexVersionSelector() const
Definition bslx_byteoutstream.h:1598
ByteOutStream & putArrayInt64(const bsls::Types::Int64 *values, int numValues)
Definition bslx_byteoutstream.h:1046
ByteOutStream & putInt16(int value)
Definition bslx_byteoutstream.h:938
ByteOutStream & putArrayFloat64(const double *values, int numValues)
Definition bslx_byteoutstream.h:1537
ByteOutStream & putUint56(bsls::Types::Uint64 value)
Definition bslx_byteoutstream.h:816
ByteOutStream & putArrayInt40(const bsls::Types::Int64 *values, int numValues)
Definition bslx_byteoutstream.h:1214
ByteOutStream & putInt64(bsls::Types::Int64 value)
Definition bslx_byteoutstream.h:764
void reset()
Definition bslx_byteoutstream.h:755
ByteOutStream & putFloat64(double value)
Definition bslx_byteoutstream.h:998
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition baljsn_encoder_testtypes.h:76
STREAM & bdexStreamOut(STREAM &stream, const TYPE &value)
Definition bslx_outstreamfunctions.h:1004
Definition bslx_byteinstream.h:377
bsl::ostream & operator<<(bsl::ostream &stream, const ByteInStream &object)
Definition bslma_usesbslmaallocator.h:344
unsigned long long Uint64
Definition bsls_types.h:139
long long Int64
Definition bsls_types.h:134
static void putArrayInt24(char *buffer, const int *values, int numValues)
static void putInt16(char *buffer, int value)
Definition bslx_marshallingutil.h:1045
static void putInt24(char *buffer, int value)
Definition bslx_marshallingutil.h:1029
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:1070
static void putArrayInt8(char *buffer, const char *values, int numValues)
Definition bslx_marshallingutil.h:1532
static void putArrayInt40(char *buffer, const bsls::Types::Int64 *values, int numValues)
@ k_SIZEOF_INT8
Definition bslx_marshallingutil.h:281
@ k_SIZEOF_INT48
Definition bslx_marshallingutil.h:276
@ k_SIZEOF_FLOAT64
Definition bslx_marshallingutil.h:282
@ k_SIZEOF_INT64
Definition bslx_marshallingutil.h:274
@ k_SIZEOF_INT24
Definition bslx_marshallingutil.h:279
@ k_SIZEOF_INT56
Definition bslx_marshallingutil.h:275
@ k_SIZEOF_INT16
Definition bslx_marshallingutil.h:280
@ k_SIZEOF_FLOAT32
Definition bslx_marshallingutil.h:283
@ k_SIZEOF_INT40
Definition bslx_marshallingutil.h:277
@ k_SIZEOF_INT32
Definition bslx_marshallingutil.h:278
static void putFloat32(char *buffer, float value)
Definition bslx_marshallingutil.h:1091
static void putInt8(char *buffer, int value)
Definition bslx_marshallingutil.h:1060
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:934
static void putInt32(char *buffer, int value)
Definition bslx_marshallingutil.h:1012
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:955
static void putInt48(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:975
static void putInt40(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:994