BDE 4.14.0 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.
264
265 // TYPES
266
267 enum {
268 // Enumerate the platform-independent sizes (in bytes) of data types in
269 // wire format. Note that the wire format size may differ from the
270 // size in memory.
271
282 };
283
284 // CLASS METHODS
285
286 // *** put scalar integral values ***
287
288 /// Load into the specified `buffer` the eight-byte, two's complement
289 /// integer (in network byte order) comprised of the least-significant
290 /// eight bytes of the specified `value` (in host byte order). The
291 /// behavior is undefined unless `buffer` has sufficient capacity. Note
292 /// that this function applies equally to unsigned 64-bit values.
293 static void putInt64(char *buffer, bsls::Types::Int64 value);
294
295 /// Load into the specified `buffer` the seven-byte, two's complement
296 /// integer (in network byte order) comprised of the least-significant
297 /// seven bytes of the specified `value` (in host byte order). The
298 /// behavior is undefined unless `buffer` has sufficient capacity. Note
299 /// that this function applies equally to unsigned 64-bit values.
300 static void putInt56(char *buffer, bsls::Types::Int64 value);
301
302 /// Load into the specified `buffer` the six-byte, two's complement
303 /// integer (in network byte order) comprised of the least-significant
304 /// six bytes of the specified `value` (in host byte order). The
305 /// behavior is undefined unless `buffer` has sufficient capacity. Note
306 /// that this function applies equally to unsigned 64-bit values.
307 static void putInt48(char *buffer, bsls::Types::Int64 value);
308
309 /// Load into the specified `buffer` the five-byte, two's complement
310 /// integer (in network byte order) comprised of the least-significant
311 /// five bytes of the specified `value` (in host byte order). The
312 /// behavior is undefined unless `buffer` has sufficient capacity. Note
313 /// that this function applies equally to unsigned 64-bit values.
314 static void putInt40(char *buffer, bsls::Types::Int64 value);
315
316 /// Load into the specified `buffer` the four-byte, two's complement
317 /// integer (in network byte order) comprised of the least-significant
318 /// four bytes of the specified `value` (in host byte order). The
319 /// behavior is undefined unless `buffer` has sufficient capacity. Note
320 /// that this function applies equally to unsigned 32-bit values, and
321 /// signed and unsigned 16- and 8-bit values.
322 static void putInt32(char *buffer, int value);
323
324 /// Load into the specified `buffer` the three-byte, two's complement
325 /// integer (in network byte order) comprised of the least-significant
326 /// three bytes of the specified `value` (in host byte order). The
327 /// behavior is undefined unless `buffer` has sufficient capacity. Note
328 /// that this function applies equally to unsigned 32-bit values, and
329 /// signed and unsigned 16- and 8-bit values.
330 static void putInt24(char *buffer, int value);
331
332 /// Load into the specified `buffer` the two-byte, two's complement
333 /// integer (in network byte order) comprised of the least-significant
334 /// two bytes of the specified `value` (in host byte order). The
335 /// behavior is undefined unless `buffer` has sufficient capacity. Note
336 /// that this function applies equally to unsigned 32-bit values, and
337 /// signed and unsigned 16- and 8-bit values.
338 static void putInt16(char *buffer, int value);
339
340 /// Load into the specified `buffer` the one-byte, two's complement
341 /// integer comprised of the least-significant one byte of the specified
342 /// `value`. The behavior is undefined unless `buffer` has sufficient
343 /// capacity. Note that this function applies equally to unsigned
344 /// 32-bit values, and signed and unsigned 16- and 8-bit values.
345 static void putInt8(char *buffer, int value);
346
347 // *** put scalar floating-point values ***
348
349 /// Load into the specified `buffer` the eight-byte IEEE
350 /// double-precision floating-point number (in network byte order)
351 /// comprised of the most-significant eight bytes of the specified
352 /// `value` (in host byte order). The behavior is undefined unless
353 /// `buffer` has sufficient capacity. Note that for non-conforming
354 /// platforms, this operation may be lossy.
355 static void putFloat64(char *buffer, double value);
356
357 /// Load into the specified `buffer` the four-byte IEEE single-precision
358 /// floating-point number (in network byte order) comprised of the
359 /// most-significant four bytes of the specified `value` (in host byte
360 /// order). The behavior is undefined unless `buffer` has sufficient
361 /// capacity. Note that for non-conforming platforms, this operation
362 /// may be lossy.
363 static void putFloat32(char *buffer, float value);
364
365 // *** get scalar integral values ***
366
367 /// Load into the specified `variable` the eight-byte, two's complement
368 /// integer (in host byte order) comprised of the initial eight bytes of
369 /// the specified `buffer` (in network byte order). The behavior is
370 /// undefined unless `buffer` has sufficient contents. Note that the
371 /// value will be sign-extended.
372 static void getInt64(bsls::Types::Int64 *variable,
373 const char *buffer);
374
375 /// Load into the specified `variable` the eight-byte, two's complement
376 /// unsigned integer (in host byte order) comprised of the initial eight
377 /// bytes of the specified `buffer` (in network byte order). The
378 /// behavior is undefined unless `buffer` has sufficient contents. Note
379 /// that the value will be zero-extended.
380 static void getUint64(bsls::Types::Uint64 *variable,
381 const char *buffer);
382
383 /// Load into the specified `variable` the seven-byte, two's complement
384 /// integer (in host byte order) comprised of the initial seven bytes of
385 /// the specified `buffer` (in network byte order). The behavior is
386 /// undefined unless `buffer` has sufficient contents. Note that the
387 /// value will be sign-extended.
388 static void getInt56(bsls::Types::Int64 *variable,
389 const char *buffer);
390
391 /// Load into the specified `variable` the seven-byte, two's complement
392 /// unsigned integer (in host byte order) comprised of the initial seven
393 /// bytes of the specified `buffer` (in network byte order). The
394 /// behavior is undefined unless `buffer` has sufficient contents. Note
395 /// that the value will be zero-extended.
396 static void getUint56(bsls::Types::Uint64 *variable,
397 const char *buffer);
398
399 /// Load into the specified `variable` the six-byte, two's complement
400 /// integer (in host byte order) comprised of the initial six bytes of
401 /// the specified `buffer` (in network byte order). The behavior is
402 /// undefined unless `buffer` has sufficient contents. Note that the
403 /// value will be sign-extended.
404 static void getInt48(bsls::Types::Int64 *variable,
405 const char *buffer);
406
407 /// Load into the specified `variable` the six-byte, two's complement
408 /// unsigned integer (in host byte order) comprised of the initial six
409 /// bytes of the specified `buffer` (in network byte order). The
410 /// behavior is undefined unless `buffer` has sufficient contents. Note
411 /// that the value will be zero-extended.
412 static void getUint48(bsls::Types::Uint64 *variable,
413 const char *buffer);
414
415 /// Load into the specified `variable` the five-byte, two's complement
416 /// integer (in host byte order) comprised of the initial five bytes of
417 /// the specified `buffer` (in network byte order). The behavior is
418 /// undefined unless `buffer` has sufficient contents. Note that the
419 /// value will be sign-extended.
420 static void getInt40(bsls::Types::Int64 *variable,
421 const char *buffer);
422
423 /// Load into the specified `variable` the five-byte, two's complement
424 /// unsigned integer (in host byte order) comprised of the initial five
425 /// bytes of the specified `buffer` (in network byte order). The
426 /// behavior is undefined unless `buffer` has sufficient contents. Note
427 /// that the value will be zero-extended.
428 static void getUint40(bsls::Types::Uint64 *variable,
429 const char *buffer);
430
431 /// Load into the specified `variable` the four-byte, two's complement
432 /// integer (in host byte order) comprised of the initial four bytes of
433 /// the specified `buffer` (in network byte order). The behavior is
434 /// undefined unless `buffer` has sufficient contents. Note that the
435 /// value will be sign-extended.
436 static void getInt32(int *variable, const char *buffer);
437
438 /// Load into the specified `variable` the four-byte, two's complement
439 /// unsigned integer (in host byte order) comprised of the initial four
440 /// bytes of the specified `buffer` (in network byte order). The
441 /// behavior is undefined unless `buffer` has sufficient contents. Note
442 /// that the value will be zero-extended.
443 static void getUint32(unsigned int *variable, const char *buffer);
444
445 /// Load into the specified `variable` the three-byte, two's complement
446 /// integer (in host byte order) comprised of the initial three bytes of
447 /// the specified `buffer` (in network byte order). The behavior is
448 /// undefined unless `buffer` has sufficient contents. Note that the
449 /// value will be sign-extended.
450 static void getInt24(int *variable, const char *buffer);
451
452 /// Load into the specified `variable` the three-byte, two's complement
453 /// unsigned integer (in host byte order) comprised of the initial three
454 /// bytes of the specified `buffer` (in network byte order). The
455 /// behavior is undefined unless `buffer` has sufficient contents. Note
456 /// that the value will be zero-extended.
457 static void getUint24(unsigned int *variable, const char *buffer);
458
459 /// Load into the specified `variable` the two-byte, two's complement
460 /// integer (in host byte order) comprised of the initial two bytes of
461 /// the specified `buffer` (in network byte order). The behavior is
462 /// undefined unless `buffer` has sufficient contents. Note that the
463 /// value will be sign-extended.
464 static void getInt16(short *variable, const char *buffer);
465
466 /// Load into the specified `variable` the two-byte, two's complement
467 /// unsigned integer (in host byte order) comprised of the initial two
468 /// bytes of the specified `buffer` (in network byte order). The
469 /// behavior is undefined unless `buffer` has sufficient contents. Note
470 /// that the value will be zero-extended.
471 static void getUint16(unsigned short *variable, const char *buffer);
472
473 static void getInt8(char *variable, const char *buffer);
474 static void getInt8(signed char *variable, const char *buffer);
475 /// Load into the specified `variable` the one-byte, two's complement
476 /// integer comprised of the initial one byte of the specified `buffer`.
477 /// The behavior is undefined unless `buffer` has sufficient contents.
478 static void getInt8(unsigned char *variable, const char *buffer);
479
480 // *** get scalar floating-point values ***
481
482 /// Load into the specified `variable` the eight-byte IEEE
483 /// double-precision floating-point number (in host byte order)
484 /// comprised of the initial eight bytes of the specified `buffer` (in
485 /// network byte order). The behavior is undefined unless `buffer` has
486 /// sufficient contents.
487 static void getFloat64(double *variable, const char *buffer);
488
489 /// Load into the specified `variable` the four-byte IEEE
490 /// single-precision floating-point number (in host byte order)
491 /// comprised of the initial four bytes of the specified `buffer` (in
492 /// network byte order). The behavior is undefined unless `buffer` has
493 /// sufficient contents.
494 static void getFloat32(float *variable, const char *buffer);
495
496 // *** put arrays of integral values ***
497
498 static void putArrayInt64(char *buffer,
499 const bsls::Types::Int64 *values,
500 int numValues);
501 /// Load into the specified `buffer` the consecutive eight-byte, two's
502 /// complement integers (in network byte order) comprised of the
503 /// least-significant eight bytes of each of the specified `numValues`
504 /// leading entries in the specified `values` (in host byte order). The
505 /// behavior is undefined unless `buffer` has sufficient capacity,
506 /// `values` has sufficient contents, and `0 <= numValues`.
507 static void putArrayInt64(char *buffer,
508 const bsls::Types::Uint64 *values,
509 int numValues);
510
511 static void putArrayInt56(char *buffer,
512 const bsls::Types::Int64 *values,
513 int numValues);
514 /// Load into the specified `buffer` the consecutive seven-byte, two's
515 /// complement integers (in network byte order) comprised of the
516 /// least-significant seven bytes of each of the specified `numValues`
517 /// leading entries in the specified `values` (in host byte order). The
518 /// behavior is undefined unless `buffer` has sufficient capacity,
519 /// `values` has sufficient contents, and `0 <= numValues`.
520 static void putArrayInt56(char *buffer,
521 const bsls::Types::Uint64 *values,
522 int numValues);
523
524 static void putArrayInt48(char *buffer,
525 const bsls::Types::Int64 *values,
526 int numValues);
527 /// Load into the specified `buffer` the consecutive six-byte, two's
528 /// complement integers (in network byte order) comprised of the
529 /// least-significant six bytes of each of the specified `numValues`
530 /// leading entries in the specified `values` (in host byte order). The
531 /// behavior is undefined unless `buffer` has sufficient capacity,
532 /// `values` has sufficient contents, and `0 <= numValues`.
533 static void putArrayInt48(char *buffer,
534 const bsls::Types::Uint64 *values,
535 int numValues);
536
537 static void putArrayInt40(char *buffer,
538 const bsls::Types::Int64 *values,
539 int numValues);
540 /// Load into the specified `buffer` the consecutive five-byte, two's
541 /// complement integers (in network byte order) comprised of the
542 /// least-significant five bytes of each of the specified `numValues`
543 /// leading entries in the specified `values` (in host byte order). The
544 /// behavior is undefined unless `buffer` has sufficient capacity,
545 /// `values` has sufficient contents, and `0 <= numValues`.
546 static void putArrayInt40(char *buffer,
547 const bsls::Types::Uint64 *values,
548 int numValues);
549
550 static void putArrayInt32(char *buffer,
551 const int *values,
552 int numValues);
553 /// Load into the specified `buffer` the consecutive four-byte, two's
554 /// complement integers (in network byte order) comprised of the
555 /// least-significant four bytes of each of the specified `numValues`
556 /// leading entries in the specified `values` (in host byte order). The
557 /// behavior is undefined unless `buffer` has sufficient capacity,
558 /// `values` has sufficient contents, and `0 <= numValues`.
559 static void putArrayInt32(char *buffer,
560 const unsigned int *values,
561 int numValues);
562
563 static void putArrayInt24(char *buffer,
564 const int *values,
565 int numValues);
566 /// Load into the specified `buffer` the consecutive three-byte, two's
567 /// complement integers (in network byte order) comprised of the
568 /// least-significant three bytes of each of the specified `numValues`
569 /// leading entries in the specified `values` (in host byte order). The
570 /// behavior is undefined unless `buffer` has sufficient capacity,
571 /// `values` has sufficient contents, and `0 <= numValues`.
572 static void putArrayInt24(char *buffer,
573 const unsigned int *values,
574 int numValues);
575
576 static void putArrayInt16(char *buffer,
577 const short *values,
578 int numValues);
579 /// Load into the specified `buffer` the consecutive two-byte, two's
580 /// complement integers (in network byte order) comprised of the
581 /// least-significant two bytes of each of the specified `numValues`
582 /// leading entries in the specified `values` (in host byte order). The
583 /// behavior is undefined unless `buffer` has sufficient capacity,
584 /// `values` has sufficient contents, and `0 <= numValues`.
585 static void putArrayInt16(char *buffer,
586 const unsigned short *values,
587 int numValues);
588
589 static void putArrayInt8(char *buffer,
590 const char *values,
591 int numValues);
592 static void putArrayInt8(char *buffer,
593 const signed char *values,
594 int numValues);
595 /// Load into the specified `buffer` the consecutive one-byte, two's
596 /// complement integers comprised of the one byte of each of the
597 /// specified `numValues` leading entries in the specified `values`.
598 /// The behavior is undefined unless `buffer` has sufficient capacity,
599 /// `values` has sufficient contents, and `0 <= numValues`.
600 static void putArrayInt8(char *buffer,
601 const unsigned char *values,
602 int numValues);
603
604 // *** put arrays of floating-point values ***
605
606 /// Load into the specified `buffer` the consecutive eight-byte IEEE
607 /// double-precision floating-point numbers (in network byte order)
608 /// comprised of the most-significant eight bytes of each of the
609 /// specified `numValues` leading entries in the specified `values` (in
610 /// host byte order). The behavior is undefined unless `buffer` has
611 /// sufficient capacity, `values` has sufficient contents, and
612 /// `0 <= numValues`. Note that for non-conforming platforms, this
613 /// operation may be lossy.
614 static void putArrayFloat64(char *buffer,
615 const double *values,
616 int numValues);
617
618 /// Load into the specified `buffer` the consecutive four-byte IEEE
619 /// single-precision floating-point numbers (in network byte order)
620 /// comprised of the most-significant four bytes of each of the
621 /// specified `numValues` leading entries in the specified `values` (in
622 /// host byte order). The behavior is undefined unless `buffer` has
623 /// sufficient capacity, `values` has sufficient contents, and
624 /// `0 <= numValues`. Note that for non-conforming platforms, this
625 /// operation may be lossy.
626 static void putArrayFloat32(char *buffer,
627 const float *values,
628 int numValues);
629
630 // *** get arrays of integral values ***
631
632 /// Load into the specified `variables` the consecutive eight-byte,
633 /// two's complement integers (in host byte order) comprised of each of
634 /// the specified `numVariables` leading eight-byte sequences in the
635 /// specified `buffer` (in network byte order). The behavior is
636 /// undefined unless `variables` has sufficient capacity, `buffer` has
637 /// sufficient contents, and `0 <= numVariables`. Note that each of the
638 /// values will be sign-extended.
639 static void getArrayInt64(bsls::Types::Int64 *variables,
640 const char *buffer,
641 int numVariables);
642
643 /// Load into the specified `variables` the consecutive eight-byte,
644 /// two's complement unsigned integers (in host byte order) comprised of
645 /// each of the specified `numVariables` leading eight-byte sequences in
646 /// the specified `buffer` (in network byte order). The behavior is
647 /// undefined unless `variables` has sufficient capacity, `buffer` has
648 /// sufficient contents, and `0 <= numVariables`. Note that each of the
649 /// values will be zero-extended.
650 static void getArrayUint64(bsls::Types::Uint64 *variables,
651 const char *buffer,
652 int numVariables);
653
654 /// Load into the specified `variables` the consecutive seven-byte,
655 /// two's complement integers (in host byte order) comprised of each of
656 /// the specified `numVariables` leading seven-byte sequences in the
657 /// specified `buffer` (in network byte order). The behavior is
658 /// undefined unless `variables` has sufficient capacity, `buffer` has
659 /// sufficient contents, and `0 <= numVariables`. Note that each of the
660 /// values will be sign-extended.
661 static void getArrayInt56(bsls::Types::Int64 *variables,
662 const char *buffer,
663 int numVariables);
664
665 /// Load into the specified `variables` the consecutive seven-byte,
666 /// two's complement unsigned integers (in host byte order) comprised of
667 /// each of the specified `numVariables` leading seven-byte sequences in
668 /// the specified `buffer` (in network byte order). The behavior is
669 /// undefined unless `variables` has sufficient capacity, `buffer` has
670 /// sufficient contents, and `0 <= numVariables`. Note that each of the
671 /// values will be zero-extended.
672 static void getArrayUint56(bsls::Types::Uint64 *variables,
673 const char *buffer,
674 int numVariables);
675
676 /// Load into the specified `variables` the consecutive six-byte, two's
677 /// complement integers (in host byte order) comprised of each of the
678 /// specified `numVariables` leading six-byte sequences in the specified
679 /// `buffer` (in network byte order). The behavior is undefined unless
680 /// `variables` has sufficient capacity, `buffer` has sufficient
681 /// contents, and `0 <= numVariables`. Note that each of the values
682 /// will be sign-extended.
683 static void getArrayInt48(bsls::Types::Int64 *variables,
684 const char *buffer,
685 int numVariables);
686
687 /// Load into the specified `variables` the consecutive six-byte, two's
688 /// complement unsigned integers (in host byte order) comprised of each
689 /// of the specified `numVariables` leading six-byte sequences in the
690 /// specified `buffer` (in network byte order). The behavior is
691 /// undefined unless `variables` has sufficient capacity, `buffer` has
692 /// sufficient contents, and `0 <= numVariables`. Note that each of the
693 /// values will be zero-extended.
694 static void getArrayUint48(bsls::Types::Uint64 *variables,
695 const char *buffer,
696 int numVariables);
697
698 /// Load into the specified `variables` the consecutive five-byte, two's
699 /// complement integers (in host byte order) comprised of each of the
700 /// specified `numVariables` leading five-byte sequences in the
701 /// specified `buffer` (in network byte order). The behavior is
702 /// undefined unless `variables` has sufficient capacity, `buffer` has
703 /// sufficient contents, and `0 <= numVariables`. Note that each of the
704 /// values will be sign-extended.
705 static void getArrayInt40(bsls::Types::Int64 *variables,
706 const char *buffer,
707 int numVariables);
708
709 /// Load into the specified `variables` the consecutive five-byte, two's
710 /// complement unsigned integers (in host byte order) comprised of each
711 /// of the specified `numVariables` leading five-byte sequences in the
712 /// specified `buffer` (in network byte order). The behavior is
713 /// undefined unless `variables` has sufficient capacity, `buffer` has
714 /// sufficient contents, and `0 <= numVariables`. Note that each of the
715 /// values will be zero-extended.
716 static void getArrayUint40(bsls::Types::Uint64 *variables,
717 const char *buffer,
718 int numVariables);
719
720 /// Load into the specified `variables` the consecutive four-byte, two's
721 /// complement integers (in host byte order) comprised of each of the
722 /// specified `numVariables` leading four-byte sequences in the
723 /// specified `buffer` (in network byte order). The behavior is
724 /// undefined unless `variables` has sufficient capacity, `buffer` has
725 /// sufficient contents, and `0 <= numVariables`. Note that each of the
726 /// values will be sign-extended.
727 static void getArrayInt32(int *variables,
728 const char *buffer,
729 int numVariables);
730
731 /// Load into the specified `variables` the consecutive four-byte, two's
732 /// complement unsigned integers (in host byte order) comprised of each
733 /// of the specified `numVariables` leading four-byte sequences in the
734 /// specified `buffer` (in network byte order). The behavior is
735 /// undefined unless `variables` has sufficient capacity, `buffer` has
736 /// sufficient contents, and `0 <= numVariables`. Note that each of the
737 /// values will be zero-extended.
738 static void getArrayUint32(unsigned int *variables,
739 const char *buffer,
740 int numVariables);
741
742 /// Load into the specified `variables` the consecutive three-byte,
743 /// two's complement integers (in host byte order) comprised of each of
744 /// the specified `numVariables` leading three-byte sequences in the
745 /// specified `buffer` (in network byte order). The behavior is
746 /// undefined unless `variables` has sufficient capacity, `buffer` has
747 /// sufficient contents, and `0 <= numVariables`. Note that each of the
748 /// values will be sign-extended.
749 static void getArrayInt24(int *variables,
750 const char *buffer,
751 int numVariables);
752
753 /// Load into the specified `variables` the consecutive three-byte,
754 /// two's complement unsigned integers (in host byte order) comprised of
755 /// each of the specified `numVariables` leading three-byte sequences in
756 /// the specified `buffer` (in network byte order). The behavior is
757 /// undefined unless `variables` has sufficient capacity, `buffer` has
758 /// sufficient contents, and `0 <= numVariables`. Note that each of the
759 /// values will be zero-extended.
760 static void getArrayUint24(unsigned int *variables,
761 const char *buffer,
762 int numVariables);
763
764 /// Load into the specified `variables` the consecutive two-byte, two's
765 /// complement integers (in host byte order) comprised of each of the
766 /// specified `numVariables` leading two-byte sequences in the specified
767 /// `buffer` (in network byte order). The behavior is undefined unless
768 /// `variables` has sufficient capacity, `buffer` has sufficient
769 /// contents, and `0 <= numVariables`. Note that each of the values
770 /// will be sign-extended.
771 static void getArrayInt16(short *variables,
772 const char *buffer,
773 int numVariables);
774
775 /// Load into the specified `variables` the consecutive two-byte, two's
776 /// complement unsigned integers (in host byte order) comprised of each
777 /// of the specified `numVariables` leading two-byte sequences in the
778 /// specified `buffer` (in network byte order). The behavior is
779 /// undefined unless `variables` has sufficient capacity, `buffer` has
780 /// sufficient contents, and `0 <= numVariables`. Note that each of the
781 /// values will be zero-extended.
782 static void getArrayUint16(unsigned short *variables,
783 const char *buffer,
784 int numVariables);
785
786 static void getArrayInt8(char *variables,
787 const char *buffer,
788 int numVariables);
789 static void getArrayInt8(signed char *variables,
790 const char *buffer,
791 int numVariables);
792 /// Load into the specified `variables` the consecutive one-byte, two's
793 /// complement integers comprised of each of the specified
794 /// `numVariables` leading one-byte sequences in the specified `buffer`.
795 /// The behavior is undefined unless `variables` has sufficient
796 /// capacity, `buffer` has sufficient contents, and `0 <= numVariables`.
797 static void getArrayInt8(unsigned char *variables,
798 const char *buffer,
799 int numVariables);
800
801 // *** get arrays of floating-point values ***
802
803 /// Load into the specified `variables` the consecutive eight-byte IEEE
804 /// double-precision floating-point numbers (in host byte order)
805 /// comprised of each of the specified `numVariables` leading eight-byte
806 /// sequences in the specified `buffer` (in network byte order). The
807 /// behavior is undefined unless `variables` has sufficient capacity,
808 /// `buffer` has sufficient contents, and `0 <= numVariables`.
809 static void getArrayFloat64(double *variables,
810 const char *buffer,
811 int numVariables);
812
813 /// Load into the specified `variables` the consecutive four-byte IEEE
814 /// single-precision floating-point numbers (in host byte order)
815 /// comprised of each of the specified `numVariables` leading four-byte
816 /// sequences in the specified `buffer` (in network byte order). The
817 /// behavior is undefined unless `variables` has sufficient capacity,
818 /// `buffer` has sufficient contents, and `0 <= numVariables`.
819 static void getArrayFloat32(float *variables,
820 const char *buffer,
821 int numVariables);
822
823};
824
825// ============================================================================
826// INLINE DEFINITIONS
827// ============================================================================
828
829 // ----------------------
830 // struct MarshallingUtil
831 // ----------------------
832
833// CLASS METHODS
834
835 // *** put scalar integral values ***
836
837inline
839{
840 BSLS_ASSERT_SAFE(buffer);
841
842 const char *bytes = reinterpret_cast<char *>(&value);
843
844#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
845 buffer[0] = bytes[7];
846 buffer[1] = bytes[6];
847 buffer[2] = bytes[5];
848 buffer[3] = bytes[4];
849 buffer[4] = bytes[3];
850 buffer[5] = bytes[2];
851 buffer[6] = bytes[1];
852 buffer[7] = bytes[0];
853#else
854 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT64, k_SIZEOF_INT64);
855#endif
856}
857
858inline
860{
861 BSLS_ASSERT_SAFE(buffer);
862
863 const char *bytes = reinterpret_cast<char *>(&value);
864
865#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
866 buffer[0] = bytes[6];
867 buffer[1] = bytes[5];
868 buffer[2] = bytes[4];
869 buffer[3] = bytes[3];
870 buffer[4] = bytes[2];
871 buffer[5] = bytes[1];
872 buffer[6] = bytes[0];
873#else
874 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT56, k_SIZEOF_INT56);
875#endif
876}
877
878inline
880{
881 BSLS_ASSERT_SAFE(buffer);
882
883 const char *bytes = reinterpret_cast<char *>(&value);
884
885#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
886 buffer[0] = bytes[5];
887 buffer[1] = bytes[4];
888 buffer[2] = bytes[3];
889 buffer[3] = bytes[2];
890 buffer[4] = bytes[1];
891 buffer[5] = bytes[0];
892#else
893 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT48, k_SIZEOF_INT48);
894#endif
895}
896
897inline
899{
900 BSLS_ASSERT_SAFE(buffer);
901
902 const char *bytes = reinterpret_cast<char *>(&value);
903
904#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
905 buffer[0] = bytes[4];
906 buffer[1] = bytes[3];
907 buffer[2] = bytes[2];
908 buffer[3] = bytes[1];
909 buffer[4] = bytes[0];
910#else
911 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT40, k_SIZEOF_INT40);
912#endif
913}
914
915inline
916void MarshallingUtil::putInt32(char *buffer, int value)
917{
918 BSLS_ASSERT_SAFE(buffer);
919
920 const char *bytes = reinterpret_cast<char *>(&value);
921
922#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
923 buffer[0] = bytes[3];
924 buffer[1] = bytes[2];
925 buffer[2] = bytes[1];
926 buffer[3] = bytes[0];
927#else
928 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT32, k_SIZEOF_INT32);
929#endif
930}
931
932inline
933void MarshallingUtil::putInt24(char *buffer, int value)
934{
935 BSLS_ASSERT_SAFE(buffer);
936
937 const char *bytes = reinterpret_cast<char *>(&value);
938
939#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
940 buffer[0] = bytes[2];
941 buffer[1] = bytes[1];
942 buffer[2] = bytes[0];
943#else
944 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT24, k_SIZEOF_INT24);
945#endif
946}
947
948inline
949void MarshallingUtil::putInt16(char *buffer, int value)
950{
951 BSLS_ASSERT_SAFE(buffer);
952
953 const char *bytes = reinterpret_cast<char *>(&value);
954
955#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
956 buffer[0] = bytes[1];
957 buffer[1] = bytes[0];
958#else
959 bsl::memcpy(buffer, bytes + sizeof value - k_SIZEOF_INT16, k_SIZEOF_INT16);
960#endif
961}
962
963inline
964void MarshallingUtil::putInt8(char *buffer, int value)
965{
966 BSLS_ASSERT_SAFE(buffer);
967
968 *buffer = static_cast<char>(value);
969}
970
971 // *** put scalar floating-point values ***
972
973inline
974void MarshallingUtil::putFloat64(char *buffer, double value)
975{
976 BSLS_ASSERT_SAFE(buffer);
977
978 const char *bytes = reinterpret_cast<char *>(&value);
979
980#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
981 buffer[0] = bytes[sizeof value - 1];
982 buffer[1] = bytes[sizeof value - 2];
983 buffer[2] = bytes[sizeof value - 3];
984 buffer[3] = bytes[sizeof value - 4];
985 buffer[4] = bytes[sizeof value - 5];
986 buffer[5] = bytes[sizeof value - 6];
987 buffer[6] = bytes[sizeof value - 7];
988 buffer[7] = bytes[sizeof value - 8];
989#else
990 bsl::memcpy(buffer, bytes, k_SIZEOF_FLOAT64);
991#endif
992}
993
994inline
995void MarshallingUtil::putFloat32(char *buffer, float value)
996{
997 BSLS_ASSERT_SAFE(buffer);
998
999 const char *bytes = reinterpret_cast<char *>(&value);
1000
1001#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1002 buffer[0] = bytes[sizeof value - 1];
1003 buffer[1] = bytes[sizeof value - 2];
1004 buffer[2] = bytes[sizeof value - 3];
1005 buffer[3] = bytes[sizeof value - 4];
1006#else
1007 bsl::memcpy(buffer, bytes, k_SIZEOF_FLOAT32);
1008#endif
1009}
1010
1011 // *** get scalar integral values ***
1012
1013inline
1015 const char *buffer)
1016{
1017 BSLS_ASSERT_SAFE(variable);
1018 BSLS_ASSERT_SAFE(buffer);
1019
1020 if (sizeof *variable > k_SIZEOF_INT64) {
1021 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1022 }
1023
1024 char *bytes = reinterpret_cast<char *>(variable);
1025
1026#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1027 bytes[7] = buffer[0];
1028 bytes[6] = buffer[1];
1029 bytes[5] = buffer[2];
1030 bytes[4] = buffer[3];
1031 bytes[3] = buffer[4];
1032 bytes[2] = buffer[5];
1033 bytes[1] = buffer[6];
1034 bytes[0] = buffer[7];
1035#else
1036 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT64,
1037 buffer,
1039#endif
1040}
1041
1042inline
1044 const char *buffer)
1045{
1046 BSLS_ASSERT_SAFE(variable);
1047 BSLS_ASSERT_SAFE(buffer);
1048
1049 if (sizeof *variable > k_SIZEOF_INT64) {
1050 *variable = 0; // zero-extend
1051 }
1052
1053 char *bytes = reinterpret_cast<char *>(variable);
1054
1055#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1056 bytes[7] = buffer[0];
1057 bytes[6] = buffer[1];
1058 bytes[5] = buffer[2];
1059 bytes[4] = buffer[3];
1060 bytes[3] = buffer[4];
1061 bytes[2] = buffer[5];
1062 bytes[1] = buffer[6];
1063 bytes[0] = buffer[7];
1064#else
1065 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT64,
1066 buffer,
1068#endif
1069}
1070
1071inline
1073 const char *buffer)
1074{
1075 BSLS_ASSERT_SAFE(variable);
1076 BSLS_ASSERT_SAFE(buffer);
1077
1078 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1079
1080 char *bytes = reinterpret_cast<char *>(variable);
1081
1082#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1083 bytes[6] = buffer[0];
1084 bytes[5] = buffer[1];
1085 bytes[4] = buffer[2];
1086 bytes[3] = buffer[3];
1087 bytes[2] = buffer[4];
1088 bytes[1] = buffer[5];
1089 bytes[0] = buffer[6];
1090#else
1091 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT56,
1092 buffer,
1094#endif
1095}
1096
1097inline
1099 const char *buffer)
1100{
1101 BSLS_ASSERT_SAFE(variable);
1102 BSLS_ASSERT_SAFE(buffer);
1103
1104 *variable = 0; // zero-extend
1105
1106 char *bytes = reinterpret_cast<char *>(variable);
1107
1108#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1109 bytes[6] = buffer[0];
1110 bytes[5] = buffer[1];
1111 bytes[4] = buffer[2];
1112 bytes[3] = buffer[3];
1113 bytes[2] = buffer[4];
1114 bytes[1] = buffer[5];
1115 bytes[0] = buffer[6];
1116#else
1117 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT56,
1118 buffer,
1120#endif
1121}
1122
1123inline
1125 const char *buffer)
1126{
1127 BSLS_ASSERT_SAFE(variable);
1128 BSLS_ASSERT_SAFE(buffer);
1129
1130 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1131
1132 char *bytes = reinterpret_cast<char *>(variable);
1133
1134#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1135 bytes[5] = buffer[0];
1136 bytes[4] = buffer[1];
1137 bytes[3] = buffer[2];
1138 bytes[2] = buffer[3];
1139 bytes[1] = buffer[4];
1140 bytes[0] = buffer[5];
1141#else
1142 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT48,
1143 buffer,
1145#endif
1146}
1147
1148inline
1150 const char *buffer)
1151{
1152 BSLS_ASSERT_SAFE(variable);
1153 BSLS_ASSERT_SAFE(buffer);
1154
1155 *variable = 0; // zero-extend
1156
1157 char *bytes = reinterpret_cast<char *>(variable);
1158
1159#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1160 bytes[5] = buffer[0];
1161 bytes[4] = buffer[1];
1162 bytes[3] = buffer[2];
1163 bytes[2] = buffer[3];
1164 bytes[1] = buffer[4];
1165 bytes[0] = buffer[5];
1166#else
1167 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT48,
1168 buffer,
1170#endif
1171}
1172
1173inline
1175 const char *buffer)
1176{
1177 BSLS_ASSERT_SAFE(variable);
1178 BSLS_ASSERT_SAFE(buffer);
1179
1180 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1181
1182 char *bytes = reinterpret_cast<char *>(variable);
1183
1184#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1185 bytes[4] = buffer[0];
1186 bytes[3] = buffer[1];
1187 bytes[2] = buffer[2];
1188 bytes[1] = buffer[3];
1189 bytes[0] = buffer[4];
1190#else
1191 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT40,
1192 buffer,
1194#endif
1195}
1196
1197inline
1199 const char *buffer)
1200{
1201 BSLS_ASSERT_SAFE(variable);
1202 BSLS_ASSERT_SAFE(buffer);
1203
1204 *variable = 0; // zero-extend
1205
1206 char *bytes = reinterpret_cast<char *>(variable);
1207
1208#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1209 bytes[4] = buffer[0];
1210 bytes[3] = buffer[1];
1211 bytes[2] = buffer[2];
1212 bytes[1] = buffer[3];
1213 bytes[0] = buffer[4];
1214#else
1215 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT40,
1216 buffer,
1218#endif
1219}
1220
1221inline
1222void MarshallingUtil::getInt32(int *variable, const char *buffer)
1223{
1224 BSLS_ASSERT_SAFE(variable);
1225 BSLS_ASSERT_SAFE(buffer);
1226
1227 if (sizeof *variable > k_SIZEOF_INT32) {
1228 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1229 }
1230
1231 char *bytes = reinterpret_cast<char *>(variable);
1232
1233#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1234 bytes[3] = buffer[0];
1235 bytes[2] = buffer[1];
1236 bytes[1] = buffer[2];
1237 bytes[0] = buffer[3];
1238#else
1239 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT32,
1240 buffer,
1242#endif
1243}
1244
1245inline
1246void MarshallingUtil::getUint32(unsigned int *variable, const char *buffer)
1247{
1248 BSLS_ASSERT_SAFE(variable);
1249 BSLS_ASSERT_SAFE(buffer);
1250
1251 if (sizeof *variable > k_SIZEOF_INT32) {
1252 *variable = 0; // zero-extend
1253 }
1254
1255 char *bytes = reinterpret_cast<char *>(variable);
1256
1257#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1258 bytes[3] = buffer[0];
1259 bytes[2] = buffer[1];
1260 bytes[1] = buffer[2];
1261 bytes[0] = buffer[3];
1262#else
1263 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT32,
1264 buffer,
1266#endif
1267}
1268
1269inline
1270void MarshallingUtil::getInt24(int *variable, const char *buffer)
1271{
1272 BSLS_ASSERT_SAFE(variable);
1273 BSLS_ASSERT_SAFE(buffer);
1274
1275 *variable = 0x80 & buffer[0] ? -1 : 0; // sign extend
1276
1277 char *bytes = reinterpret_cast<char *>(variable);
1278
1279#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1280 bytes[2] = buffer[0];
1281 bytes[1] = buffer[1];
1282 bytes[0] = buffer[2];
1283#else
1284 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT24,
1285 buffer,
1287#endif
1288}
1289
1290inline
1291void MarshallingUtil::getUint24(unsigned int *variable, const char *buffer)
1292{
1293 BSLS_ASSERT_SAFE(variable);
1294 BSLS_ASSERT_SAFE(buffer);
1295
1296 *variable = 0; // zero-extend
1297
1298 char *bytes = reinterpret_cast<char *>(variable);
1299
1300#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1301 bytes[2] = buffer[0];
1302 bytes[1] = buffer[1];
1303 bytes[0] = buffer[2];
1304#else
1305 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT24,
1306 buffer,
1308#endif
1309}
1310
1311inline
1312void MarshallingUtil::getInt16(short *variable, const char *buffer)
1313{
1314 BSLS_ASSERT_SAFE(variable);
1315 BSLS_ASSERT_SAFE(buffer);
1316
1317 if (sizeof *variable > k_SIZEOF_INT16) {
1318 *variable = static_cast<short>(0x80 & buffer[0] ? -1 : 0);
1319 // sign extend
1320 }
1321
1322 char *bytes = reinterpret_cast<char *>(variable);
1323
1324#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1325 bytes[1] = buffer[0];
1326 bytes[0] = buffer[1];
1327#else
1328 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT16,
1329 buffer,
1331#endif
1332}
1333
1334inline
1335void MarshallingUtil::getUint16(unsigned short *variable, const char *buffer)
1336{
1337 BSLS_ASSERT_SAFE(variable);
1338 BSLS_ASSERT_SAFE(buffer);
1339
1340 if (sizeof *variable > k_SIZEOF_INT16) {
1341 *variable = 0; // zero-extend
1342 }
1343
1344 char *bytes = reinterpret_cast<char *>(variable);
1345
1346#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1347 bytes[1] = buffer[0];
1348 bytes[0] = buffer[1];
1349#else
1350 bsl::memcpy(bytes + sizeof *variable - k_SIZEOF_INT16,
1351 buffer,
1353#endif
1354}
1355
1356inline
1357void MarshallingUtil::getInt8(char *variable, const char *buffer)
1358{
1359 BSLS_ASSERT_SAFE(variable);
1360 BSLS_ASSERT_SAFE(buffer);
1361
1362 *variable = *buffer;
1363}
1364
1365inline
1366void MarshallingUtil::getInt8(signed char *variable, const char *buffer)
1367{
1368 BSLS_ASSERT_SAFE(variable);
1369 BSLS_ASSERT_SAFE(buffer);
1370
1371 getInt8(reinterpret_cast<char *>(variable), buffer);
1372}
1373
1374inline
1375void MarshallingUtil::getInt8(unsigned char *variable, const char *buffer)
1376{
1377 BSLS_ASSERT_SAFE(variable);
1378 BSLS_ASSERT_SAFE(buffer);
1379
1380 getInt8(reinterpret_cast<char *>(variable), buffer);
1381}
1382
1383 // *** get scalar floating-point values ***
1384
1385inline
1386void MarshallingUtil::getFloat64(double *variable, const char *buffer)
1387{
1388 BSLS_ASSERT_SAFE(variable);
1389 BSLS_ASSERT_SAFE(buffer);
1390
1391 if (sizeof *variable > k_SIZEOF_FLOAT64) {
1392 *variable = 0; // zero-fill significand
1393 }
1394
1395 char *bytes = reinterpret_cast<char *>(variable);
1396
1397#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1398 bytes[sizeof *variable - 1] = buffer[0];
1399 bytes[sizeof *variable - 2] = buffer[1];
1400 bytes[sizeof *variable - 3] = buffer[2];
1401 bytes[sizeof *variable - 4] = buffer[3];
1402 bytes[sizeof *variable - 5] = buffer[4];
1403 bytes[sizeof *variable - 6] = buffer[5];
1404 bytes[sizeof *variable - 7] = buffer[6];
1405 bytes[sizeof *variable - 8] = buffer[7];
1406#else
1407 bsl::memcpy(bytes, buffer, k_SIZEOF_FLOAT64);
1408#endif
1409}
1410
1411inline
1412void MarshallingUtil::getFloat32(float *variable, const char *buffer)
1413{
1414 BSLS_ASSERT_SAFE(variable);
1415 BSLS_ASSERT_SAFE(buffer);
1416
1417 if (sizeof *variable > k_SIZEOF_FLOAT32) {
1418 *variable = 0; // zero-fill significand
1419 }
1420
1421 char *bytes = reinterpret_cast<char *>(variable);
1422
1423#if BSLS_PLATFORM_IS_LITTLE_ENDIAN
1424 bytes[sizeof *variable - 1] = buffer[0];
1425 bytes[sizeof *variable - 2] = buffer[1];
1426 bytes[sizeof *variable - 3] = buffer[2];
1427 bytes[sizeof *variable - 4] = buffer[3];
1428#else
1429 bsl::memcpy(bytes, buffer, k_SIZEOF_FLOAT32);
1430#endif
1431}
1432
1433 // *** put arrays of integral values ***
1434
1435inline
1437 const char *values,
1438 int numValues)
1439{
1440 BSLS_ASSERT_SAFE(buffer);
1441 BSLS_ASSERT_SAFE(values);
1442 BSLS_ASSERT_SAFE(0 <= numValues);
1443
1444 bsl::memcpy(buffer, values, numValues);
1445}
1446
1447inline
1449 const signed char *values,
1450 int numValues)
1451{
1452 BSLS_ASSERT_SAFE(buffer);
1453 BSLS_ASSERT_SAFE(values);
1454 BSLS_ASSERT_SAFE(0 <= numValues);
1455
1456 putArrayInt8(buffer, reinterpret_cast<const char *>(values), numValues);
1457}
1458
1459inline
1461 const unsigned char *values,
1462 int numValues)
1463{
1464 BSLS_ASSERT_SAFE(buffer);
1465 BSLS_ASSERT_SAFE(values);
1466 BSLS_ASSERT_SAFE(0 <= numValues);
1467
1468 putArrayInt8(buffer, reinterpret_cast<const char *>(values), numValues);
1469}
1470
1471 // *** get arrays of integral values ***
1472
1473inline
1475 const char *buffer,
1476 int numVariables)
1477{
1478 BSLS_ASSERT_SAFE(variables);
1479 BSLS_ASSERT_SAFE(buffer);
1480 BSLS_ASSERT_SAFE(0 <= numVariables);
1481
1482 bsl::memcpy(variables, buffer, numVariables);
1483}
1484
1485inline
1486void MarshallingUtil::getArrayInt8(signed char *variables,
1487 const char *buffer,
1488 int numVariables)
1489{
1490 BSLS_ASSERT_SAFE(variables);
1491 BSLS_ASSERT_SAFE(buffer);
1492 BSLS_ASSERT_SAFE(0 <= numVariables);
1493
1494 getArrayInt8(reinterpret_cast<char *>(variables), buffer, numVariables);
1495}
1496
1497inline
1498void MarshallingUtil::getArrayInt8(unsigned char *variables,
1499 const char *buffer,
1500 int numVariables)
1501{
1502 BSLS_ASSERT_SAFE(variables);
1503 BSLS_ASSERT_SAFE(buffer);
1504 BSLS_ASSERT_SAFE(0 <= numVariables);
1505
1506 getArrayInt8(reinterpret_cast<char *>(variables), buffer, numVariables);
1507}
1508
1509} // close package namespace
1510
1511
1512#endif
1513
1514// ----------------------------------------------------------------------------
1515// Copyright 2014 Bloomberg Finance L.P.
1516//
1517// Licensed under the Apache License, Version 2.0 (the "License");
1518// you may not use this file except in compliance with the License.
1519// You may obtain a copy of the License at
1520//
1521// http://www.apache.org/licenses/LICENSE-2.0
1522//
1523// Unless required by applicable law or agreed to in writing, software
1524// distributed under the License is distributed on an "AS IS" BASIS,
1525// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1526// See the License for the specific language governing permissions and
1527// limitations under the License.
1528// ----------------------------- END-OF-FILE ----------------------------------
1529
1530/** @} */
1531/** @} */
1532/** @} */
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslx_byteinstream.h:377
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132
Definition bslx_marshallingutil.h:263
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:949
static void putInt24(char *buffer, int value)
Definition bslx_marshallingutil.h:933
static void putArrayInt48(char *buffer, const bsls::Types::Int64 *values, int numValues)
static void 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:1291
static void getInt56(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1072
static void getInt32(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1222
static void getFloat32(float *variable, const char *buffer)
Definition bslx_marshallingutil.h:1412
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:1335
static void getUint64(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1043
static void getInt40(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1174
static void getUint56(bsls::Types::Uint64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1098
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:1014
static void putArrayInt48(char *buffer, const bsls::Types::Uint64 *values, int numValues)
static void putFloat64(char *buffer, double value)
Definition bslx_marshallingutil.h:974
static void putArrayInt8(char *buffer, const char *values, int numValues)
Definition bslx_marshallingutil.h:1436
static void 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:279
@ k_SIZEOF_INT48
Definition bslx_marshallingutil.h:274
@ k_SIZEOF_FLOAT64
Definition bslx_marshallingutil.h:280
@ k_SIZEOF_INT64
Definition bslx_marshallingutil.h:272
@ k_SIZEOF_INT24
Definition bslx_marshallingutil.h:277
@ k_SIZEOF_INT56
Definition bslx_marshallingutil.h:273
@ k_SIZEOF_INT16
Definition bslx_marshallingutil.h:278
@ k_SIZEOF_FLOAT32
Definition bslx_marshallingutil.h:281
@ k_SIZEOF_INT40
Definition bslx_marshallingutil.h:275
@ k_SIZEOF_INT32
Definition bslx_marshallingutil.h:276
static void putFloat32(char *buffer, float value)
Definition bslx_marshallingutil.h:995
static void 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:1474
static void putInt8(char *buffer, int value)
Definition bslx_marshallingutil.h:964
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:1312
static void getArrayUint32(unsigned int *variables, const char *buffer, int numVariables)
static void getFloat64(double *variable, const char *buffer)
Definition bslx_marshallingutil.h:1386
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:1149
static void putArrayInt64(char *buffer, const bsls::Types::Int64 *values, int numValues)
static void getInt24(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1270
static void putInt64(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:838
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:1198
static void putInt32(char *buffer, int value)
Definition bslx_marshallingutil.h:916
static void putArrayInt16(char *buffer, const short *values, int numValues)
static void putArrayFloat32(char *buffer, const float *values, int numValues)
static void putInt56(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:859
static void putArrayInt16(char *buffer, const unsigned short *values, int numValues)
static void getInt48(bsls::Types::Int64 *variable, const char *buffer)
Definition bslx_marshallingutil.h:1124
static void getUint32(unsigned int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1246
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:879
static void getInt8(char *variable, const char *buffer)
Definition bslx_marshallingutil.h:1357
static void putInt40(char *buffer, bsls::Types::Int64 value)
Definition bslx_marshallingutil.h:898
static void getArrayUint24(unsigned int *variables, const char *buffer, int numVariables)