BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslx_marshallingutil.h
Go to the documentation of this file.
1/// @file bslx_marshallingutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslx_marshallingutil.h -*-C++-*-
8#ifndef INCLUDED_BSLX_MARSHALLINGUTIL
9#define INCLUDED_BSLX_MARSHALLINGUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslx_marshallingutil bslx_marshallingutil
15/// @brief Support platform-independent marshalling of fundamental types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslx
19/// @{
20/// @addtogroup bslx_marshallingutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslx_marshallingutil-purpose"> Purpose</a>
25/// * <a href="#bslx_marshallingutil-classes"> Classes </a>
26/// * <a href="#bslx_marshallingutil-description"> Description </a>
27/// * <a href="#bslx_marshallingutil-note-on-function-naming-and-interface"> Note on Function Naming and Interface </a>
28/// * <a href="#bslx_marshallingutil-ieee-754-double-precision-format"> IEEE 754 Double-Precision Format </a>
29/// * <a href="#bslx_marshallingutil-ieee-754-single-precision-format"> IEEE 754 Single-Precision Format </a>
30/// * <a href="#bslx_marshallingutil-usage"> Usage </a>
31/// * <a href="#bslx_marshallingutil-example-1-round-trip-marshalling"> Example 1: Round-Trip Marshalling </a>
32///
33/// # Purpose {#bslx_marshallingutil-purpose}
34/// Support platform-independent marshalling of fundamental types.
35///
36/// # Classes {#bslx_marshallingutil-classes}
37///
38/// - bslx::MarshallingUtil: namespace for put/get marshalling functions
39///
40/// @see bslx_byteinstream, bslx_byteoutstream
41///
42/// # Description {#bslx_marshallingutil-description}
43/// This component provides a byte-array-based implementation,
44/// `bslx::MarshallingUtil`, for a suite of marshalling functions used to
45/// convert values (and arrays of values) of the following fundamental integer
46/// and floating-point types:
47/// @code
48/// C++ TYPE REQUIRED CONTENT OF ANY PLATFORM-NEUTRAL FORMAT
49/// -------- -----------------------------------------------
50/// Int64 least significant 64 bits (signed)
51/// Uint64 least significant 64 bits (unsigned)
52/// int least significant 32 bits (signed)
53/// unsigned int least significant 32 bits (unsigned)
54/// short least significant 16 bits (signed)
55/// unsigned short least significant 16 bits (unsigned)
56/// char least significant 8 bits (platform-dependent)
57/// signed char least significant 8 bits (signed)
58/// unsigned char least significant 8 bits (unsigned)
59/// double IEEE standard 8-byte floating-point value
60/// float IEEE standard 4-byte floating-point value
61/// @endcode
62/// In addition to basic marshalling functions, where each marshalled instance
63/// of a fundamental type occupies the same number of bytes in the stream
64/// (regardless of its value), this component provides an interface for
65/// efficient marshalling of integer types. In particular, 64-bit values can be
66/// streamed as 40-, 48-, 56-, or 64-bit values, and 32-bit values can be
67/// streamed as 24- or 32-bit values. Marshalled integers are written and
68/// assumed to be in two's complement, big-endian format (i.e., network byte
69/// order). Floating-point formats are described below.
70///
71/// ## Note on Function Naming and Interface {#bslx_marshallingutil-note-on-function-naming-and-interface}
72///
73///
74/// The names and interfaces of the functions of `bslx::MarshallingUtil` follow
75/// a systematic fashion explained below. This makes it easier to guess the
76/// name and signature of the intended function. In what follows, `buffer` is
77/// always of type `char *` or `const char *` depending on whether it is used as
78/// an input or an output, and `variable` and `value` are of a type that depends
79/// on the name of the function and intended width, with `variable` used as an
80/// output, while `value` is used as an input.
81///
82/// Here are the `get...` functions for integral and floating-point scalar
83/// types:
84/// @code
85/// Name Type of 'variable' Notes
86/// ---- ------------------ -----
87/// getIntNN(variable, buffer) bsls::Types::Int64 * NN=64,56,48,40
88/// int * NN=32,24
89/// short * NN=16
90/// char * NN=8
91/// signed char * NN=8
92/// unsigned char * NN=8
93///
94/// getUintNN(variable, buffer) bsls::Types::Uint64 * NN=64,56,48,40
95/// unsigned int * NN=32,24
96/// unsigned short * NN=16
97///
98/// getFloatNN(variable, buffer) double * NN=64
99/// float * NN=32
100/// @endcode
101/// Here are the `put...` functions for scalar types. Note that there is no
102/// `putUintNN` since `putIntNN` applies equally to unsigned `NN`-bit values
103/// (through a conversion to a signed value):
104/// @code
105/// Name Type of 'value' Notes
106/// ---- --------------- -----
107/// putIntNN(buffer, value) bsls::Types::Int64 NN=64,56,48,40
108/// int NN=32,24,16,8
109///
110/// putFloatNN(buffer, value) double NN=64
111/// float NN=32
112/// @endcode
113/// Here are the `getArray...` functions for integral and floating-point scalar
114/// array types:
115/// @code
116/// Name Type of 'variables' Notes
117/// ---- ---------------- -----
118/// getArrayIntNN(variables, bsls::Types::Int64 * NN=64,56,48,40
119/// buffer, int * NN=32,24
120/// numVariables) short * NN=16
121/// char * NN=8
122/// signed char * NN=8
123/// unsigned char * NN=8
124///
125/// getArrayUintNN(variables, bsls::Types::Uint64 * NN=64,56,48,40
126/// buffer, unsigned int * NN=32,24
127/// numVariables) unsigned short * NN=16
128///
129/// getArrayFloatNN(variables, double * NN=64
130/// buffer, float * NN=32
131/// numVariables)
132/// @endcode
133/// Finally, the `putArray...` functions follow. Note that this time there is
134/// an overload for unsigned types, but that the function name is still
135/// `putArrayInt...` for arrays of both signed and unsigned integrals:
136/// @code
137/// Name Type of 'values' Notes
138/// ---- --------------- -----
139/// putArrayIntNN(buffer, const bsls::Types::Int64 * NN=64,56,48,40
140/// values, const bsls::Types::Uint64 * NN=64,56,48,40
141/// numValues) const int * NN=32,24
142/// const unsigned int * NN=32,24
143/// const short * NN=16
144/// const unsigned short * NN=16
145/// const char * NN=8
146/// const signed char * NN=8
147/// const unsigned char * NN=8
148///
149/// putArrayFloatNN(buffer, const double * NN=64
150/// values, const float * NN=32
151/// numValues)
152/// @endcode
153///
154/// ## IEEE 754 Double-Precision Format {#bslx_marshallingutil-ieee-754-double-precision-format}
155///
156///
157/// A `double` is assumed to be *at* *least* 64 bits in size. The externalized
158/// byte representation of a 64-bit floating-point value is defined to conform
159/// to the IEEE double-precision format illustrated below. If the native
160/// representation of a 64-bit floating-point value does not match this format,
161/// a conversion process to and from this format is performed. This conversion
162/// may (of course) be lossy:
163/// @code
164/// sign bit 11-bit exponent 52-bit significand
165/// / / /
166/// +-+-----------+----------------------------------------------------+
167/// |s|e10......e0|m51...............................................m0|
168/// +-+-----------+----------------------------------------------------+
169/// LSB MSB
170/// @endcode
171///
172/// ## IEEE 754 Single-Precision Format {#bslx_marshallingutil-ieee-754-single-precision-format}
173///
174///
175/// A `float` is assumed to be *at* *least* 32 bits in size. The externalized
176/// byte representation of a 32-bit floating-point value is defined to conform
177/// to the IEEE single-precision format illustrated below. If the native
178/// representation of a 32-bit floating-point value does not match this format,
179/// a conversion process to and from this format is performed. This conversion
180/// may (of course) be lossy:
181/// @code
182/// sign bit 8-bit exponent 23-bit significand
183/// / / /
184/// +-+--------+-----------------------+
185/// |s|e7....e0|m22..................m0|
186/// +-+--------+-----------------------+
187/// LSB MSB
188/// @endcode
189///
190/// ## Usage {#bslx_marshallingutil-usage}
191///
192///
193/// This section illustrates intended use of this component.
194///
195/// ### Example 1: Round-Trip Marshalling {#bslx_marshallingutil-example-1-round-trip-marshalling}
196///
197///
198/// The `bslx::MarshallingUtil` component can be used stand-alone to marshal a
199/// platform-neutral representation of fundamental data and arrays of
200/// fundamental data to and from a buffer. In this example, the round-trip
201/// marshalling of an `int` and an array of `int` values will be demonstrated.
202/// First, declare the buffer and the data to be marshalled:
203/// @code
204/// char buffer[32];
205/// int value = 17;
206/// int values[] = { 1, 2, 3 };
207/// @endcode
208/// Then, marshal all data into the `buffer`:
209/// @code
210/// bslx::MarshallingUtil::putInt32(buffer + 0, value);
211/// bslx::MarshallingUtil::putArrayInt32(buffer + 4, values, 3);
212/// @endcode
213/// Next, declare variables to hold the values to be extracted from the
214/// `buffer`:
215/// @code
216/// int newValue = 0;
217/// int newValues[] = { 0, 0, 0 };
218/// @endcode
219/// Finally, marshal the data from the `buffer` to these variables and confirm
220/// the round-trip marshalling was successful:
221/// @code
222/// bslx::MarshallingUtil::getInt32(&newValue, buffer + 0);
223/// bslx::MarshallingUtil::getArrayInt32(newValues, buffer + 4, 3);
224///
225/// assert(newValue == value);
226/// assert(newValues[0] == values[0]);
227/// assert(newValues[1] == values[1]);
228/// assert(newValues[2] == values[2]);
229/// @endcode
230/// @}
231/** @} */
232/** @} */
233
234/** @addtogroup bsl
235 * @{
236 */
237/** @addtogroup bslx
238 * @{
239 */
240/** @addtogroup bslx_marshallingutil
241 * @{
242 */
243
244#include <bslscm_version.h>
245
246#include <bsls_assert.h>
247#include <bsls_platform.h>
248#include <bsls_types.h>
249
250#include <bsl_cstring.h> // for 'bsl::memcpy'
251
252
253namespace bslx {
254
255 // ======================
256 // struct MarshallingUtil
257 // ======================
258
259/// This `struct` provides a namespace for a suite of functions that
260/// facilitate the marshalling of values, and C-style arrays of values, of
261/// the fundamental integral and floating-point types in a data-independent,
262/// platform-neutral representation.
263///
264/// See @ref bslx_marshallingutil
266
267 // TYPES
268
269 enum {
270 // Enumerate the platform-independent sizes (in bytes) of data types in
271 // wire format. Note that the wire format size may differ from the
272 // size in memory.
273
284 };
285
286 // CLASS METHODS
287
288 // *** put scalar integral values ***
289
290 /// Load into the specified `buffer` the eight-byte, two's complement
291 /// integer (in network byte order) comprised of the least-significant
292 /// eight bytes of the specified `value` (in host byte order).
293 ///
294 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
295 ///
296 /// \note Note that this function applies equally to unsigned 64-bit values.
297 static void putInt64(char *buffer, bsls::Types::Int64 value);
298
299 /// Load into the specified `buffer` the seven-byte, two's complement
300 /// integer (in network byte order) comprised of the least-significant
301 /// seven bytes of the specified `value` (in host byte order).
302 ///
303 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
304 ///
305 /// \note Note that this function applies equally to unsigned 64-bit values.
306 static void putInt56(char *buffer, bsls::Types::Int64 value);
307
308 /// Load into the specified `buffer` the six-byte, two's complement
309 /// integer (in network byte order) comprised of the least-significant
310 /// six bytes of the specified `value` (in host byte order).
311 ///
312 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
313 ///
314 /// \note Note that this function applies equally to unsigned 64-bit values.
315 static void putInt48(char *buffer, bsls::Types::Int64 value);
316
317 /// Load into the specified `buffer` the five-byte, two's complement
318 /// integer (in network byte order) comprised of the least-significant
319 /// five bytes of the specified `value` (in host byte order).
320 ///
321 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
322 ///
323 /// \note Note that this function applies equally to unsigned 64-bit values.
324 static void putInt40(char *buffer, bsls::Types::Int64 value);
325
326 /// Load into the specified `buffer` the four-byte, two's complement
327 /// integer (in network byte order) comprised of the least-significant
328 /// four bytes of the specified `value` (in host byte order).
329 ///
330 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
331 ///
332 /// \note Note that this function applies equally to unsigned 32-bit values, and
333 /// signed and unsigned 16- and 8-bit values.
334 static void putInt32(char *buffer, int value);
335
336 /// Load into the specified `buffer` the three-byte, two's complement
337 /// integer (in network byte order) comprised of the least-significant
338 /// three bytes of the specified `value` (in host byte order).
339 ///
340 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
341 ///
342 /// \note Note that this function applies equally to unsigned 32-bit values, and
343 /// signed and unsigned 16- and 8-bit values.
344 static void putInt24(char *buffer, int value);
345
346 /// Load into the specified `buffer` the two-byte, two's complement
347 /// integer (in network byte order) comprised of the least-significant
348 /// two bytes of the specified `value` (in host byte order).
349 ///
350 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
351 ///
352 /// \note Note that this function applies equally to unsigned 32-bit values, and
353 /// signed and unsigned 16- and 8-bit values.
354 static void putInt16(char *buffer, int value);
355
356 /// Load into the specified `buffer` the one-byte, two's complement
357 /// integer comprised of the least-significant one byte of the specified `value`.
358 ///
359 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
360 ///
361 /// \note Note that this function applies equally to unsigned
362 /// 32-bit values, and signed and unsigned 16- and 8-bit values.
363 static void putInt8(char *buffer, int value);
364
365 // *** put scalar floating-point values ***
366
367 /// Load into the specified `buffer` the eight-byte IEEE
368 /// double-precision floating-point number (in network byte order)
369 /// comprised of the most-significant eight bytes of the specified `value` (in host byte order).
370 ///
371 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
372 ///
373 /// \note Note that for non-conforming
374 /// platforms, this operation may be lossy.
375 static void putFloat64(char *buffer, double value);
376
377 /// Load into the specified `buffer` the four-byte IEEE single-precision
378 /// floating-point number (in network byte order) comprised of the
379 /// most-significant four bytes of the specified `value` (in host byte order).
380 ///
381 /// \pre The behavior is undefined unless `buffer` has sufficient capacity.
382 ///
383 /// \note Note that for non-conforming platforms, this operation
384 /// may be lossy.
385 static void putFloat32(char *buffer, float value);
386
387 // *** get scalar integral values ***
388
389 /// Load into the specified `variable` the eight-byte, two's complement
390 /// integer (in host byte order) comprised of the initial eight bytes of
391 /// the specified `buffer` (in network byte order).
392 ///
393 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
394 /// \note Note that the
395 /// value will be sign-extended.
396 static void getInt64(bsls::Types::Int64 *variable,
397 const char *buffer);
398
399 /// Load into the specified `variable` the eight-byte, two's complement
400 /// unsigned integer (in host byte order) comprised of the initial eight
401 /// bytes of the specified `buffer` (in network byte order).
402 ///
403 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
404 ///
405 /// \note Note that the value will be zero-extended.
406 static void getUint64(bsls::Types::Uint64 *variable,
407 const char *buffer);
408
409 /// Load into the specified `variable` the seven-byte, two's complement
410 /// integer (in host byte order) comprised of the initial seven bytes of
411 /// the specified `buffer` (in network byte order).
412 ///
413 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
414 /// \note Note that the
415 /// value will be sign-extended.
416 static void getInt56(bsls::Types::Int64 *variable,
417 const char *buffer);
418
419 /// Load into the specified `variable` the seven-byte, two's complement
420 /// unsigned integer (in host byte order) comprised of the initial seven
421 /// bytes of the specified `buffer` (in network byte order).
422 ///
423 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
424 ///
425 /// \note Note that the value will be zero-extended.
426 static void getUint56(bsls::Types::Uint64 *variable,
427 const char *buffer);
428
429 /// Load into the specified `variable` the six-byte, two's complement
430 /// integer (in host byte order) comprised of the initial six bytes of
431 /// the specified `buffer` (in network byte order).
432 ///
433 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
434 /// \note Note that the
435 /// value will be sign-extended.
436 static void getInt48(bsls::Types::Int64 *variable,
437 const char *buffer);
438
439 /// Load into the specified `variable` the six-byte, two's complement
440 /// unsigned integer (in host byte order) comprised of the initial six
441 /// bytes of the specified `buffer` (in network byte order).
442 ///
443 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
444 ///
445 /// \note Note that the value will be zero-extended.
446 static void getUint48(bsls::Types::Uint64 *variable,
447 const char *buffer);
448
449 /// Load into the specified `variable` the five-byte, two's complement
450 /// integer (in host byte order) comprised of the initial five bytes of
451 /// the specified `buffer` (in network byte order).
452 ///
453 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
454 /// \note Note that the
455 /// value will be sign-extended.
456 static void getInt40(bsls::Types::Int64 *variable,
457 const char *buffer);
458
459 /// Load into the specified `variable` the five-byte, two's complement
460 /// unsigned integer (in host byte order) comprised of the initial five
461 /// bytes of the specified `buffer` (in network byte order).
462 ///
463 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
464 ///
465 /// \note Note that the value will be zero-extended.
466 static void getUint40(bsls::Types::Uint64 *variable,
467 const char *buffer);
468
469 /// Load into the specified `variable` the four-byte, two's complement
470 /// integer (in host byte order) comprised of the initial four bytes of
471 /// the specified `buffer` (in network byte order).
472 ///
473 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
474 /// \note Note that the
475 /// value will be sign-extended.
476 static void getInt32(int *variable, const char *buffer);
477
478 /// Load into the specified `variable` the four-byte, two's complement
479 /// unsigned integer (in host byte order) comprised of the initial four
480 /// bytes of the specified `buffer` (in network byte order).
481 ///
482 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
483 ///
484 /// \note Note that the value will be zero-extended.
485 static void getUint32(unsigned int *variable, const char *buffer);
486
487 /// Load into the specified `variable` the three-byte, two's complement
488 /// integer (in host byte order) comprised of the initial three bytes of
489 /// the specified `buffer` (in network byte order).
490 ///
491 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
492 /// \note Note that the
493 /// value will be sign-extended.
494 static void getInt24(int *variable, const char *buffer);
495
496 /// Load into the specified `variable` the three-byte, two's complement
497 /// unsigned integer (in host byte order) comprised of the initial three
498 /// bytes of the specified `buffer` (in network byte order).
499 ///
500 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
501 ///
502 /// \note Note that the value will be zero-extended.
503 static void getUint24(unsigned int *variable, const char *buffer);
504
505 /// Load into the specified `variable` the two-byte, two's complement
506 /// integer (in host byte order) comprised of the initial two bytes of
507 /// the specified `buffer` (in network byte order).
508 ///
509 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
510 /// \note Note that the
511 /// value will be sign-extended.
512 static void getInt16(short *variable, const char *buffer);
513
514 /// Load into the specified `variable` the two-byte, two's complement
515 /// unsigned integer (in host byte order) comprised of the initial two
516 /// bytes of the specified `buffer` (in network byte order).
517 ///
518 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
519 ///
520 /// \note Note that the value will be zero-extended.
521 static void getUint16(unsigned short *variable, const char *buffer);
522
523 /// Load into the specified `variable` the one-byte, two's complement
524 /// integer comprised of the initial one byte of the specified `buffer`.
525 ///
526 /// \pre The behavior is undefined unless `buffer` has sufficient contents.
527 static void getInt8(char *variable, const char *buffer);
528 static void getInt8(signed char *variable, const char *buffer);
529 static void getInt8(unsigned char *variable, const char *buffer);
530
531 // *** get scalar floating-point values ***
532
533 /// Load into the specified `variable` the eight-byte IEEE
534 /// double-precision floating-point number (in host byte order)
535 /// comprised of the initial eight bytes of the specified `buffer` (in network byte order).
536 ///
537 /// \pre The behavior is undefined unless `buffer` has
538 /// sufficient contents.
539 static void getFloat64(double *variable, const char *buffer);
540
541 /// Load into the specified `variable` the four-byte IEEE
542 /// single-precision floating-point number (in host byte order)
543 /// comprised of the initial four bytes of the specified `buffer` (in network byte order).
544 ///
545 /// \pre The behavior is undefined unless `buffer` has
546 /// sufficient contents.
547 static void getFloat32(float *variable, const char *buffer);
548
549 // *** put arrays of integral values ***
550
551 /// Load into the specified `buffer` the consecutive eight-byte, two's
552 /// complement integers (in network byte order) comprised of the
553 /// least-significant eight bytes of each of the specified `numValues`
554 /// leading entries in the specified `values` (in host byte order).
555 ///
556 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
557 /// `values` has sufficient contents, and `0 <= numValues`.
558 static void putArrayInt64(char *buffer,
559 const bsls::Types::Int64 *values,
560 int numValues);
561 static void putArrayInt64(char *buffer,
562 const bsls::Types::Uint64 *values,
563 int numValues);
564
565 /// Load into the specified `buffer` the consecutive seven-byte, two's
566 /// complement integers (in network byte order) comprised of the
567 /// least-significant seven bytes of each of the specified `numValues`
568 /// leading entries in the specified `values` (in host byte order).
569 ///
570 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
571 /// `values` has sufficient contents, and `0 <= numValues`.
572 static void putArrayInt56(char *buffer,
573 const bsls::Types::Int64 *values,
574 int numValues);
575 static void putArrayInt56(char *buffer,
576 const bsls::Types::Uint64 *values,
577 int numValues);
578
579 /// Load into the specified `buffer` the consecutive six-byte, two's
580 /// complement integers (in network byte order) comprised of the
581 /// least-significant six bytes of each of the specified `numValues`
582 /// leading entries in the specified `values` (in host byte order).
583 ///
584 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
585 /// `values` has sufficient contents, and `0 <= numValues`.
586 static void putArrayInt48(char *buffer,
587 const bsls::Types::Int64 *values,
588 int numValues);
589 static void putArrayInt48(char *buffer,
590 const bsls::Types::Uint64 *values,
591 int numValues);
592
593 /// Load into the specified `buffer` the consecutive five-byte, two's
594 /// complement integers (in network byte order) comprised of the
595 /// least-significant five bytes of each of the specified `numValues`
596 /// leading entries in the specified `values` (in host byte order).
597 ///
598 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
599 /// `values` has sufficient contents, and `0 <= numValues`.
600 static void putArrayInt40(char *buffer,
601 const bsls::Types::Int64 *values,
602 int numValues);
603 static void putArrayInt40(char *buffer,
604 const bsls::Types::Uint64 *values,
605 int numValues);
606
607 /// Load into the specified `buffer` the consecutive four-byte, two's
608 /// complement integers (in network byte order) comprised of the
609 /// least-significant four bytes of each of the specified `numValues`
610 /// leading entries in the specified `values` (in host byte order).
611 ///
612 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
613 /// `values` has sufficient contents, and `0 <= numValues`.
614 static void putArrayInt32(char *buffer,
615 const int *values,
616 int numValues);
617 static void putArrayInt32(char *buffer,
618 const unsigned int *values,
619 int numValues);
620
621 /// Load into the specified `buffer` the consecutive three-byte, two's
622 /// complement integers (in network byte order) comprised of the
623 /// least-significant three bytes of each of the specified `numValues`
624 /// leading entries in the specified `values` (in host byte order).
625 ///
626 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
627 /// `values` has sufficient contents, and `0 <= numValues`.
628 static void putArrayInt24(char *buffer,
629 const int *values,
630 int numValues);
631 static void putArrayInt24(char *buffer,
632 const unsigned int *values,
633 int numValues);
634
635 /// Load into the specified `buffer` the consecutive two-byte, two's
636 /// complement integers (in network byte order) comprised of the
637 /// least-significant two bytes of each of the specified `numValues`
638 /// leading entries in the specified `values` (in host byte order).
639 ///
640 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
641 /// `values` has sufficient contents, and `0 <= numValues`.
642 static void putArrayInt16(char *buffer,
643 const short *values,
644 int numValues);
645 static void putArrayInt16(char *buffer,
646 const unsigned short *values,
647 int numValues);
648
649 /// Load into the specified `buffer` the consecutive one-byte, two's
650 /// complement integers comprised of the one byte of each of the
651 /// specified `numValues` leading entries in the specified `values`.
652 ///
653 /// \pre The behavior is undefined unless `buffer` has sufficient capacity,
654 /// `values` has sufficient contents, and `0 <= numValues`.
655 static void putArrayInt8(char *buffer,
656 const char *values,
657 int numValues);
658 static void putArrayInt8(char *buffer,
659 const signed char *values,
660 int numValues);
661 static void putArrayInt8(char *buffer,
662 const unsigned char *values,
663 int numValues);
664
665 // *** put arrays of floating-point values ***
666
667 /// Load into the specified `buffer` the consecutive eight-byte IEEE
668 /// double-precision floating-point numbers (in network byte order)
669 /// comprised of the most-significant eight bytes of each of the
670 /// specified `numValues` leading entries in the specified `values` (in host byte order).
671 ///
672 /// \pre The behavior is undefined unless `buffer` has
673 /// sufficient capacity, `values` has sufficient contents, and `0 <= numValues`.
674 ///
675 /// \note Note that for non-conforming platforms, this
676 /// operation may be lossy.
677 static void putArrayFloat64(char *buffer,
678 const double *values,
679 int numValues);
680
681 /// Load into the specified `buffer` the consecutive four-byte IEEE
682 /// single-precision floating-point numbers (in network byte order)
683 /// comprised of the most-significant four bytes of each of the
684 /// specified `numValues` leading entries in the specified `values` (in host byte order).
685 ///
686 /// \pre The behavior is undefined unless `buffer` has
687 /// sufficient capacity, `values` has sufficient contents, and `0 <= numValues`.
688 ///
689 /// \note Note that for non-conforming platforms, this
690 /// operation may be lossy.
691 static void putArrayFloat32(char *buffer,
692 const float *values,
693 int numValues);
694
695 // *** get arrays of integral values ***
696
697 /// Load into the specified `variables` the consecutive eight-byte,
698 /// two's complement integers (in host byte order) comprised of each of
699 /// the specified `numVariables` leading eight-byte sequences in the
700 /// specified `buffer` (in network byte order).
701 ///
702 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
703 ///
704 /// \note Note that each of the
705 /// values will be sign-extended.
706 static void getArrayInt64(bsls::Types::Int64 *variables,
707 const char *buffer,
708 int numVariables);
709
710 /// Load into the specified `variables` the consecutive eight-byte,
711 /// two's complement unsigned integers (in host byte order) comprised of
712 /// each of the specified `numVariables` leading eight-byte sequences in
713 /// the specified `buffer` (in network byte order).
714 ///
715 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
716 ///
717 /// \note Note that each of the
718 /// values will be zero-extended.
719 static void getArrayUint64(bsls::Types::Uint64 *variables,
720 const char *buffer,
721 int numVariables);
722
723 /// Load into the specified `variables` the consecutive seven-byte,
724 /// two's complement integers (in host byte order) comprised of each of
725 /// the specified `numVariables` leading seven-byte sequences in the
726 /// specified `buffer` (in network byte order).
727 ///
728 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
729 ///
730 /// \note Note that each of the
731 /// values will be sign-extended.
732 static void getArrayInt56(bsls::Types::Int64 *variables,
733 const char *buffer,
734 int numVariables);
735
736 /// Load into the specified `variables` the consecutive seven-byte,
737 /// two's complement unsigned integers (in host byte order) comprised of
738 /// each of the specified `numVariables` leading seven-byte sequences in
739 /// the specified `buffer` (in network byte order).
740 ///
741 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
742 ///
743 /// \note Note that each of the
744 /// values will be zero-extended.
745 static void getArrayUint56(bsls::Types::Uint64 *variables,
746 const char *buffer,
747 int numVariables);
748
749 /// Load into the specified `variables` the consecutive six-byte, two's
750 /// complement integers (in host byte order) comprised of each of the
751 /// specified `numVariables` leading six-byte sequences in the specified `buffer` (in network byte order).
752 ///
753 /// \pre The behavior is undefined unless
754 /// `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
755 ///
756 /// \note Note that each of the values
757 /// will be sign-extended.
758 static void getArrayInt48(bsls::Types::Int64 *variables,
759 const char *buffer,
760 int numVariables);
761
762 /// Load into the specified `variables` the consecutive six-byte, two's
763 /// complement unsigned integers (in host byte order) comprised of each
764 /// of the specified `numVariables` leading six-byte sequences in the
765 /// specified `buffer` (in network byte order).
766 ///
767 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
768 ///
769 /// \note Note that each of the
770 /// values will be zero-extended.
771 static void getArrayUint48(bsls::Types::Uint64 *variables,
772 const char *buffer,
773 int numVariables);
774
775 /// Load into the specified `variables` the consecutive five-byte, two's
776 /// complement integers (in host byte order) comprised of each of the
777 /// specified `numVariables` leading five-byte sequences in the
778 /// specified `buffer` (in network byte order).
779 ///
780 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
781 ///
782 /// \note Note that each of the
783 /// values will be sign-extended.
784 static void getArrayInt40(bsls::Types::Int64 *variables,
785 const char *buffer,
786 int numVariables);
787
788 /// Load into the specified `variables` the consecutive five-byte, two's
789 /// complement unsigned integers (in host byte order) comprised of each
790 /// of the specified `numVariables` leading five-byte sequences in the
791 /// specified `buffer` (in network byte order).
792 ///
793 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
794 ///
795 /// \note Note that each of the
796 /// values will be zero-extended.
797 static void getArrayUint40(bsls::Types::Uint64 *variables,
798 const char *buffer,
799 int numVariables);
800
801 /// Load into the specified `variables` the consecutive four-byte, two's
802 /// complement integers (in host byte order) comprised of each of the
803 /// specified `numVariables` leading four-byte sequences in the
804 /// specified `buffer` (in network byte order).
805 ///
806 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
807 ///
808 /// \note Note that each of the
809 /// values will be sign-extended.
810 static void getArrayInt32(int *variables,
811 const char *buffer,
812 int numVariables);
813
814 /// Load into the specified `variables` the consecutive four-byte, two's
815 /// complement unsigned integers (in host byte order) comprised of each
816 /// of the specified `numVariables` leading four-byte sequences in the
817 /// specified `buffer` (in network byte order).
818 ///
819 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
820 ///
821 /// \note Note that each of the
822 /// values will be zero-extended.
823 static void getArrayUint32(unsigned int *variables,
824 const char *buffer,
825 int numVariables);
826
827 /// Load into the specified `variables` the consecutive three-byte,
828 /// two's complement integers (in host byte order) comprised of each of
829 /// the specified `numVariables` leading three-byte sequences in the
830 /// specified `buffer` (in network byte order).
831 ///
832 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
833 ///
834 /// \note Note that each of the
835 /// values will be sign-extended.
836 static void getArrayInt24(int *variables,
837 const char *buffer,
838 int numVariables);
839
840 /// Load into the specified `variables` the consecutive three-byte,
841 /// two's complement unsigned integers (in host byte order) comprised of
842 /// each of the specified `numVariables` leading three-byte sequences in
843 /// the specified `buffer` (in network byte order).
844 ///
845 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
846 ///
847 /// \note Note that each of the
848 /// values will be zero-extended.
849 static void getArrayUint24(unsigned int *variables,
850 const char *buffer,
851 int numVariables);
852
853 /// Load into the specified `variables` the consecutive two-byte, two's
854 /// complement integers (in host byte order) comprised of each of the
855 /// specified `numVariables` leading two-byte sequences in the specified `buffer` (in network byte order).
856 ///
857 /// \pre The behavior is undefined unless
858 /// `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
859 ///
860 /// \note Note that each of the values
861 /// will be sign-extended.
862 static void getArrayInt16(short *variables,
863 const char *buffer,
864 int numVariables);
865
866 /// Load into the specified `variables` the consecutive two-byte, two's
867 /// complement unsigned integers (in host byte order) comprised of each
868 /// of the specified `numVariables` leading two-byte sequences in the
869 /// specified `buffer` (in network byte order).
870 ///
871 /// \pre The behavior is undefined unless `variables` has sufficient capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
872 ///
873 /// \note Note that each of the
874 /// values will be zero-extended.
875 static void getArrayUint16(unsigned short *variables,
876 const char *buffer,
877 int numVariables);
878
879 /// Load into the specified `variables` the consecutive one-byte, two's
880 /// complement integers comprised of each of the specified
881 /// `numVariables` leading one-byte sequences in the specified `buffer`.
882 ///
883 /// \pre The behavior is undefined unless `variables` has sufficient
884 /// capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
885 static void getArrayInt8(char *variables,
886 const char *buffer,
887 int numVariables);
888 static void getArrayInt8(signed char *variables,
889 const char *buffer,
890 int numVariables);
891 static void getArrayInt8(unsigned char *variables,
892 const char *buffer,
893 int numVariables);
894
895 // *** get arrays of floating-point values ***
896
897 /// Load into the specified `variables` the consecutive eight-byte IEEE
898 /// double-precision floating-point numbers (in host byte order)
899 /// comprised of each of the specified `numVariables` leading eight-byte
900 /// sequences in the specified `buffer` (in network byte order).
901 ///
902 /// \pre The behavior is undefined unless `variables` has sufficient capacity,
903 /// `buffer` has sufficient contents, and `0 <= numVariables`.
904 static void getArrayFloat64(double *variables,
905 const char *buffer,
906 int numVariables);
907
908 /// Load into the specified `variables` the consecutive four-byte IEEE
909 /// single-precision floating-point numbers (in host byte order)
910 /// comprised of each of the specified `numVariables` leading four-byte
911 /// sequences in the specified `buffer` (in network byte order).
912 ///
913 /// \pre The behavior is undefined unless `variables` has sufficient capacity,
914 /// `buffer` has sufficient contents, and `0 <= numVariables`.
915 static void getArrayFloat32(float *variables,
916 const char *buffer,
917 int numVariables);
918
919};
920
921// ============================================================================
922// INLINE DEFINITIONS
923// ============================================================================
924
925 // ----------------------
926 // struct MarshallingUtil
927 // ----------------------
928
929// CLASS METHODS
930
931 // *** put scalar integral values ***
932
933inline
935{
936 BSLS_ASSERT_SAFE(buffer);
937
938 const char *bytes = reinterpret_cast<char *>(&value);
939
940#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
941 buffer[0] = bytes[7];
942 buffer[1] = bytes[6];
943 buffer[2] = bytes[5];
944 buffer[3] = bytes[4];
945 buffer[4] = bytes[3];
946 buffer[5] = bytes[2];
947 buffer[6] = bytes[1];
948 buffer[7] = bytes[0];
949#else
950 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT64, k_SIZEOF_INT64);
951#endif
952}
953
954inline
956{
957 BSLS_ASSERT_SAFE(buffer);
958
959 const char *bytes = reinterpret_cast<char *>(&value);
960
961#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
962 buffer[0] = bytes[6];
963 buffer[1] = bytes[5];
964 buffer[2] = bytes[4];
965 buffer[3] = bytes[3];
966 buffer[4] = bytes[2];
967 buffer[5] = bytes[1];
968 buffer[6] = bytes[0];
969#else
970 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT56, k_SIZEOF_INT56);
971#endif
972}
973
974inline
976{
977 BSLS_ASSERT_SAFE(buffer);
978
979 const char *bytes = reinterpret_cast<char *>(&value);
980
981#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
982 buffer[0] = bytes[5];
983 buffer[1] = bytes[4];
984 buffer[2] = bytes[3];
985 buffer[3] = bytes[2];
986 buffer[4] = bytes[1];
987 buffer[5] = bytes[0];
988#else
989 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT48, k_SIZEOF_INT48);
990#endif
991}
992
993inline
995{
996 BSLS_ASSERT_SAFE(buffer);
997
998 const char *bytes = reinterpret_cast<char *>(&value);
999
1000#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1001 buffer[0] = bytes[4];
1002 buffer[1] = bytes[3];
1003 buffer[2] = bytes[2];
1004 buffer[3] = bytes[1];
1005 buffer[4] = bytes[0];
1006#else
1007 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT40, k_SIZEOF_INT40);
1008#endif
1009}
1010
1011inline
1012void MarshallingUtil::putInt32(char *buffer, int value)
1013{
1014 BSLS_ASSERT_SAFE(buffer);
1015
1016 const char *bytes = reinterpret_cast<char *>(&value);
1017
1018#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1019 buffer[0] = bytes[3];
1020 buffer[1] = bytes[2];
1021 buffer[2] = bytes[1];
1022 buffer[3] = bytes[0];
1023#else
1024 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT32, k_SIZEOF_INT32);
1025#endif
1026}
1027
1028inline
1029void MarshallingUtil::putInt24(char *buffer, int value)
1030{
1031 BSLS_ASSERT_SAFE(buffer);
1032
1033 const char *bytes = reinterpret_cast<char *>(&value);
1034
1035#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1036 buffer[0] = bytes[2];
1037 buffer[1] = bytes[1];
1038 buffer[2] = bytes[0];
1039#else
1040 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT24, k_SIZEOF_INT24);
1041#endif
1042}
1043
1044inline
1045void MarshallingUtil::putInt16(char *buffer, int value)
1046{
1047 BSLS_ASSERT_SAFE(buffer);
1048
1049 const char *bytes = reinterpret_cast<char *>(&value);
1050
1051#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1052 buffer[0] = bytes[1];
1053 buffer[1] = bytes[0];
1054#else
1055 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT16, k_SIZEOF_INT16);
1056#endif
1057}
1058
1059inline
1060void MarshallingUtil::putInt8(char *buffer, int value)
1061{
1062 BSLS_ASSERT_SAFE(buffer);
1063
1064 *buffer = static_cast<char>(value);
1065}
1066
1067 // *** put scalar floating-point values ***
1068
1069inline
1070void MarshallingUtil::putFloat64(char *buffer, double value)
1071{
1072 BSLS_ASSERT_SAFE(buffer);
1073
1074 const char *bytes = reinterpret_cast<char *>(&value);
1075
1076#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1077 buffer[0] = bytes[sizeof value - 1];
1078 buffer[1] = bytes[sizeof value - 2];
1079 buffer[2] = bytes[sizeof value - 3];
1080 buffer[3] = bytes[sizeof value - 4];
1081 buffer[4] = bytes[sizeof value - 5];
1082 buffer[5] = bytes[sizeof value - 6];
1083 buffer[6] = bytes[sizeof value - 7];
1084 buffer[7] = bytes[sizeof value - 8];
1085#else
1086 bsl::memcpy(buffer, bytes, k_SIZEOF_FLOAT64);
1087#endif
1088}
1089
1090inline
1091void MarshallingUtil::putFloat32(char *buffer, float value)
1092{
1093 BSLS_ASSERT_SAFE(buffer);
1094
1095 const char *bytes = reinterpret_cast<char *>(&value);
1096
1097#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1098 buffer[0] = bytes[sizeof value - 1];
1099 buffer[1] = bytes[sizeof value - 2];
1100 buffer[2] = bytes[sizeof value - 3];
1101 buffer[3] = bytes[sizeof value - 4];
1102#else
1103 bsl::memcpy(buffer, bytes, k_SIZEOF_FLOAT32);
1104#endif
1105}
1106
1107 // *** get scalar integral values ***
1108
1109inline
1111 const char *buffer)
1112{
1113 BSLS_ASSERT_SAFE(variable);
1114 BSLS_ASSERT_SAFE(buffer);
1115
1116 if (sizeof *variable > k_SIZEOF_INT64) {
1117 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1118 }
1119
1120 char *bytes = reinterpret_cast<char *>(variable);
1121
1122#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1123 bytes[7] = buffer[0];
1124 bytes[6] = buffer[1];
1125 bytes[5] = buffer[2];
1126 bytes[4] = buffer[3];
1127 bytes[3] = buffer[4];
1128 bytes[2] = buffer[5];
1129 bytes[1] = buffer[6];
1130 bytes[0] = buffer[7];
1131#else
1132 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT64,
1133 buffer,
1135#endif
1136}
1137
1138inline
1140 const char *buffer)
1141{
1142 BSLS_ASSERT_SAFE(variable);
1143 BSLS_ASSERT_SAFE(buffer);
1144
1145 if (sizeof *variable > k_SIZEOF_INT64) {
1146 *variable = 0; // zero-extend
1147 }
1148
1149 char *bytes = reinterpret_cast<char *>(variable);
1150
1151#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1152 bytes[7] = buffer[0];
1153 bytes[6] = buffer[1];
1154 bytes[5] = buffer[2];
1155 bytes[4] = buffer[3];
1156 bytes[3] = buffer[4];
1157 bytes[2] = buffer[5];
1158 bytes[1] = buffer[6];
1159 bytes[0] = buffer[7];
1160#else
1161 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT64,
1162 buffer,
1164#endif
1165}
1166
1167inline
1169 const char *buffer)
1170{
1171 BSLS_ASSERT_SAFE(variable);
1172 BSLS_ASSERT_SAFE(buffer);
1173
1174 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1175
1176 char *bytes = reinterpret_cast<char *>(variable);
1177
1178#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1179 bytes[6] = buffer[0];
1180 bytes[5] = buffer[1];
1181 bytes[4] = buffer[2];
1182 bytes[3] = buffer[3];
1183 bytes[2] = buffer[4];
1184 bytes[1] = buffer[5];
1185 bytes[0] = buffer[6];
1186#else
1187 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT56,
1188 buffer,
1190#endif
1191}
1192
1193inline
1195 const char *buffer)
1196{
1197 BSLS_ASSERT_SAFE(variable);
1198 BSLS_ASSERT_SAFE(buffer);
1199
1200 *variable = 0; // zero-extend
1201
1202 char *bytes = reinterpret_cast<char *>(variable);
1203
1204#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1205 bytes[6] = buffer[0];
1206 bytes[5] = buffer[1];
1207 bytes[4] = buffer[2];
1208 bytes[3] = buffer[3];
1209 bytes[2] = buffer[4];
1210 bytes[1] = buffer[5];
1211 bytes[0] = buffer[6];
1212#else
1213 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT56,
1214 buffer,
1216#endif
1217}
1218
1219inline
1221 const char *buffer)
1222{
1223 BSLS_ASSERT_SAFE(variable);
1224 BSLS_ASSERT_SAFE(buffer);
1225
1226 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1227
1228 char *bytes = reinterpret_cast<char *>(variable);
1229
1230#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1231 bytes[5] = buffer[0];
1232 bytes[4] = buffer[1];
1233 bytes[3] = buffer[2];
1234 bytes[2] = buffer[3];
1235 bytes[1] = buffer[4];
1236 bytes[0] = buffer[5];
1237#else
1238 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT48,
1239 buffer,
1241#endif
1242}
1243
1244inline
1246 const char *buffer)
1247{
1248 BSLS_ASSERT_SAFE(variable);
1249 BSLS_ASSERT_SAFE(buffer);
1250
1251 *variable = 0; // zero-extend
1252
1253 char *bytes = reinterpret_cast<char *>(variable);
1254
1255#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1256 bytes[5] = buffer[0];
1257 bytes[4] = buffer[1];
1258 bytes[3] = buffer[2];
1259 bytes[2] = buffer[3];
1260 bytes[1] = buffer[4];
1261 bytes[0] = buffer[5];
1262#else
1263 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT48,
1264 buffer,
1266#endif
1267}
1268
1269inline
1271 const char *buffer)
1272{
1273 BSLS_ASSERT_SAFE(variable);
1274 BSLS_ASSERT_SAFE(buffer);
1275
1276 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1277
1278 char *bytes = reinterpret_cast<char *>(variable);
1279
1280#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1281 bytes[4] = buffer[0];
1282 bytes[3] = buffer[1];
1283 bytes[2] = buffer[2];
1284 bytes[1] = buffer[3];
1285 bytes[0] = buffer[4];
1286#else
1287 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT40,
1288 buffer,
1290#endif
1291}
1292
1293inline
1295 const char *buffer)
1296{
1297 BSLS_ASSERT_SAFE(variable);
1298 BSLS_ASSERT_SAFE(buffer);
1299
1300 *variable = 0; // zero-extend
1301
1302 char *bytes = reinterpret_cast<char *>(variable);
1303
1304#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1305 bytes[4] = buffer[0];
1306 bytes[3] = buffer[1];
1307 bytes[2] = buffer[2];
1308 bytes[1] = buffer[3];
1309 bytes[0] = buffer[4];
1310#else
1311 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT40,
1312 buffer,
1314#endif
1315}
1316
1317inline
1318void MarshallingUtil::getInt32(int *variable, const char *buffer)
1319{
1320 BSLS_ASSERT_SAFE(variable);
1321 BSLS_ASSERT_SAFE(buffer);
1322
1323 if (sizeof *variable > k_SIZEOF_INT32) {
1324 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1325 }
1326
1327 char *bytes = reinterpret_cast<char *>(variable);
1328
1329#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1330 bytes[3] = buffer[0];
1331 bytes[2] = buffer[1];
1332 bytes[1] = buffer[2];
1333 bytes[0] = buffer[3];
1334#else
1335 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT32,
1336 buffer,
1338#endif
1339}
1340
1341inline
1342void MarshallingUtil::getUint32(unsigned int *variable, const char *buffer)
1343{
1344 BSLS_ASSERT_SAFE(variable);
1345 BSLS_ASSERT_SAFE(buffer);
1346
1347 if (sizeof *variable > k_SIZEOF_INT32) {
1348 *variable = 0; // zero-extend
1349 }
1350
1351 char *bytes = reinterpret_cast<char *>(variable);
1352
1353#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1354 bytes[3] = buffer[0];
1355 bytes[2] = buffer[1];
1356 bytes[1] = buffer[2];
1357 bytes[0] = buffer[3];
1358#else
1359 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT32,
1360 buffer,
1362#endif
1363}
1364
1365inline
1366void MarshallingUtil::getInt24(int *variable, const char *buffer)
1367{
1368 BSLS_ASSERT_SAFE(variable);
1369 BSLS_ASSERT_SAFE(buffer);
1370
1371 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1372
1373 char *bytes = reinterpret_cast<char *>(variable);
1374
1375#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1376 bytes[2] = buffer[0];
1377 bytes[1] = buffer[1];
1378 bytes[0] = buffer[2];
1379#else
1380 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT24,
1381 buffer,
1383#endif
1384}
1385
1386inline
1387void MarshallingUtil::getUint24(unsigned int *variable, const char *buffer)
1388{
1389 BSLS_ASSERT_SAFE(variable);
1390 BSLS_ASSERT_SAFE(buffer);
1391
1392 *variable = 0; // zero-extend
1393
1394 char *bytes = reinterpret_cast<char *>(variable);
1395
1396#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1397 bytes[2] = buffer[0];
1398 bytes[1] = buffer[1];
1399 bytes[0] = buffer[2];
1400#else
1401 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT24,
1402 buffer,
1404#endif
1405}
1406
1407inline
1408void MarshallingUtil::getInt16(short *variable, const char *buffer)
1409{
1410 BSLS_ASSERT_SAFE(variable);
1411 BSLS_ASSERT_SAFE(buffer);
1412
1413 if (sizeof *variable > k_SIZEOF_INT16) {
1414 *variable = static_cast<short>(0x80 & buffer[0] ? -1 : 0);
1415 // sign extend
1416 }
1417
1418 char *bytes = reinterpret_cast<char *>(variable);
1419
1420#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1421 bytes[1] = buffer[0];
1422 bytes[0] = buffer[1];
1423#else
1424 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT16,
1425 buffer,
1427#endif
1428}
1429
1430inline
1431void MarshallingUtil::getUint16(unsigned short *variable, const char *buffer)
1432{
1433 BSLS_ASSERT_SAFE(variable);
1434 BSLS_ASSERT_SAFE(buffer);
1435
1436 if (sizeof *variable > k_SIZEOF_INT16) {
1437 *variable = 0; // zero-extend
1438 }
1439
1440 char *bytes = reinterpret_cast<char *>(variable);
1441
1442#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1443 bytes[1] = buffer[0];
1444 bytes[0] = buffer[1];
1445#else
1446 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT16,
1447 buffer,
1449#endif
1450}
1451
1452inline
1453void MarshallingUtil::getInt8(char *variable, const char *buffer)
1454{
1455 BSLS_ASSERT_SAFE(variable);
1456 BSLS_ASSERT_SAFE(buffer);
1457
1458 *variable = *buffer;
1459}
1460
1461inline
1462void MarshallingUtil::getInt8(signed char *variable, const char *buffer)
1463{
1464 BSLS_ASSERT_SAFE(variable);
1465 BSLS_ASSERT_SAFE(buffer);
1466
1467 getInt8(reinterpret_cast<char *>(variable), buffer);
1468}
1469
1470inline
1471void MarshallingUtil::getInt8(unsigned char *variable, const char *buffer)
1472{
1473 BSLS_ASSERT_SAFE(variable);
1474 BSLS_ASSERT_SAFE(buffer);
1475
1476 getInt8(reinterpret_cast<char *>(variable), buffer);
1477}
1478
1479 // *** get scalar floating-point values ***
1480
1481inline
1482void MarshallingUtil::getFloat64(double *variable, const char *buffer)
1483{
1484 BSLS_ASSERT_SAFE(variable);
1485 BSLS_ASSERT_SAFE(buffer);
1486
1487 if (sizeof *variable > k_SIZEOF_FLOAT64) {
1488 *variable = 0; // zero-fill significand
1489 }
1490
1491 char *bytes = reinterpret_cast<char *>(variable);
1492
1493#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1494 bytes[sizeof *variable - 1] = buffer[0];
1495 bytes[sizeof *variable - 2] = buffer[1];
1496 bytes[sizeof *variable - 3] = buffer[2];
1497 bytes[sizeof *variable - 4] = buffer[3];
1498 bytes[sizeof *variable - 5] = buffer[4];
1499 bytes[sizeof *variable - 6] = buffer[5];
1500 bytes[sizeof *variable - 7] = buffer[6];
1501 bytes[sizeof *variable - 8] = buffer[7];
1502#else
1503 bsl::memcpy(bytes, buffer, k_SIZEOF_FLOAT64);
1504#endif
1505}
1506
1507inline
1508void MarshallingUtil::getFloat32(float *variable, const char *buffer)
1509{
1510 BSLS_ASSERT_SAFE(variable);
1511 BSLS_ASSERT_SAFE(buffer);
1512
1513 if (sizeof *variable > k_SIZEOF_FLOAT32) {
1514 *variable = 0; // zero-fill significand
1515 }
1516
1517 char *bytes = reinterpret_cast<char *>(variable);
1518
1519#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1520 bytes[sizeof *variable - 1] = buffer[0];
1521 bytes[sizeof *variable - 2] = buffer[1];
1522 bytes[sizeof *variable - 3] = buffer[2];
1523 bytes[sizeof *variable - 4] = buffer[3];
1524#else
1525 bsl::memcpy(bytes, buffer, k_SIZEOF_FLOAT32);
1526#endif
1527}
1528
1529 // *** put arrays of integral values ***
1530
1531inline
1533 const char *values,
1534 int numValues)
1535{
1536 BSLS_ASSERT_SAFE(buffer);
1537 BSLS_ASSERT_SAFE(values);
1538 BSLS_ASSERT_SAFE(0 <= numValues);
1539
1540 bsl::memcpy(buffer, values, numValues);
1541}
1542
1543inline
1545 const signed char *values,
1546 int numValues)
1547{
1548 BSLS_ASSERT_SAFE(buffer);
1549 BSLS_ASSERT_SAFE(values);
1550 BSLS_ASSERT_SAFE(0 <= numValues);
1551
1552 putArrayInt8(buffer, reinterpret_cast<const char *>(values), numValues);
1553}
1554
1555inline
1557 const unsigned char *values,
1558 int numValues)
1559{
1560 BSLS_ASSERT_SAFE(buffer);
1561 BSLS_ASSERT_SAFE(values);
1562 BSLS_ASSERT_SAFE(0 <= numValues);
1563
1564 putArrayInt8(buffer, reinterpret_cast<const char *>(values), numValues);
1565}
1566
1567 // *** get arrays of integral values ***
1568
1569inline
1571 const char *buffer,
1572 int numVariables)
1573{
1574 BSLS_ASSERT_SAFE(variables);
1575 BSLS_ASSERT_SAFE(buffer);
1576 BSLS_ASSERT_SAFE(0 <= numVariables);
1577
1578 bsl::memcpy(variables, buffer, numVariables);
1579}
1580
1581inline
1582void MarshallingUtil::getArrayInt8(signed char *variables,
1583 const char *buffer,
1584 int numVariables)
1585{
1586 BSLS_ASSERT_SAFE(variables);
1587 BSLS_ASSERT_SAFE(buffer);
1588 BSLS_ASSERT_SAFE(0 <= numVariables);
1589
1590 getArrayInt8(reinterpret_cast<char *>(variables), buffer, numVariables);
1591}
1592
1593inline
1594void MarshallingUtil::getArrayInt8(unsigned char *variables,
1595 const char *buffer,
1596 int numVariables)
1597{
1598 BSLS_ASSERT_SAFE(variables);
1599 BSLS_ASSERT_SAFE(buffer);
1600 BSLS_ASSERT_SAFE(0 <= numVariables);
1601
1602 getArrayInt8(reinterpret_cast<char *>(variables), buffer, numVariables);
1603}
1604
1605} // close package namespace
1606
1607
1608#endif
1609
1610// ----------------------------------------------------------------------------
1611// Copyright 2014 Bloomberg Finance L.P.
1612//
1613// Licensed under the Apache License, Version 2.0 (the "License");
1614// you may not use this file except in compliance with the License.
1615// You may obtain a copy of the License at
1616//
1617// http://www.apache.org/licenses/LICENSE-2.0
1618//
1619// Unless required by applicable law or agreed to in writing, software
1620// distributed under the License is distributed on an "AS IS" BASIS,
1621// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1622// See the License for the specific language governing permissions and
1623// limitations under the License.
1624// ----------------------------- END-OF-FILE ----------------------------------
1625
1626/** @} */
1627/** @} */
1628/** @} */
#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
Definition bslx_byteinstream.h:377
unsigned long long Uint64
Definition bsls_types.h:139
long long Int64
Definition bsls_types.h:134
Definition bslx_marshallingutil.h:265
static void getArrayFloat64(double *variables, const char *buffer, int numVariables)
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 getArrayInt24(int *variables, const char *buffer, int numVariables)
static void putArrayInt56(char *buffer, const bsls::Types::Uint64 *values, int numValues)
static void getUint24(unsigned int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1387
static void getInt56(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1168
static void getInt32(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1318
static void getFloat32(float *variable, const char *buffer)
Definition bslx_marshallingutil.h:1508
static void getArrayUint48(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void getArrayFloat32(float *variables, const char *buffer, int numVariables)
static void putArrayInt64(char *buffer, const bsls::Types::Uint64 *values, int numValues)
static void getUint16(unsigned short *variable, const char *buffer)
Definition bslx_marshallingutil.h:1431
static void getUint64(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1139
static void getInt40(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1270
static void getUint56(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1194
static void putArrayFloat64(char *buffer, const double *values, int numValues)
static void putArrayInt32(char *buffer, const int *values, int numValues)
static void getInt64(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1110
static void putArrayInt48(char *buffer, const bsls::Types::Uint64 *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 getArrayInt56(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
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 putArrayInt24(char *buffer, const unsigned int *values, int numValues)
static void getArrayInt32(int *variables, const char *buffer, int numVariables)
static void putArrayInt40(char *buffer, const bsls::Types::Uint64 *values, int numValues)
static void getArrayUint64(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void getArrayInt48(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
static void getArrayInt8(char *variables, const char *buffer, int numVariables)
Definition bslx_marshallingutil.h:1570
static void putInt8(char *buffer, int value)
Definition bslx_marshallingutil.h:1060
static void getArrayUint56(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void putArrayInt56(char *buffer, const bsls::Types::Int64 *values, int numValues)
static void putArrayInt32(char *buffer, const unsigned int *values, int numValues)
static void getArrayUint16(unsigned short *variables, const char *buffer, int numVariables)
static void getInt16(short *variable, const char *buffer)
Definition bslx_marshallingutil.h:1408
static void getArrayUint32(unsigned int *variables, const char *buffer, int numVariables)
static void getFloat64(double *variable, const char *buffer)
Definition bslx_marshallingutil.h:1482
static void getArrayInt64(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
static void getUint48(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1245
static void putArrayInt64(char *buffer, const bsls::Types::Int64 *values, int numValues)
static void getInt24(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1366
static void putInt64(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:934
static void getArrayInt40(bsls::Types::Int64 *variables, const char *buffer, int numVariables)
static void getArrayInt16(short *variables, const char *buffer, int numVariables)
static void getUint40(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1294
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 putArrayInt16(char *buffer, const unsigned short *values, int numValues)
static void getInt48(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1220
static void getUint32(unsigned int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1342
static void getArrayUint40(bsls::Types::Uint64 *variables, const char *buffer, int numVariables)
static void putInt48(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:975
static void getInt8(char *variable, const char *buffer)
Definition bslx_marshallingutil.h:1453
static void putInt40(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:994
static void getArrayUint24(unsigned int *variables, const char *buffer, int numVariables)