BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslx_marshallingutil

Detailed Description

Outline

Purpose

Support platform-independent marshalling of fundamental types.

Classes

See also
bslx_byteinstream, bslx_byteoutstream

Description

This component provides a byte-array-based implementation, bslx::MarshallingUtil, for a suite of marshalling functions used to convert values (and arrays of values) of the following fundamental integer and floating-point types:

C++ TYPE REQUIRED CONTENT OF ANY PLATFORM-NEUTRAL FORMAT
-------- -----------------------------------------------
Int64 least significant 64 bits (signed)
Uint64 least significant 64 bits (unsigned)
int least significant 32 bits (signed)
unsigned int least significant 32 bits (unsigned)
short least significant 16 bits (signed)
unsigned short least significant 16 bits (unsigned)
char least significant 8 bits (platform-dependent)
signed char least significant 8 bits (signed)
unsigned char least significant 8 bits (unsigned)
double IEEE standard 8-byte floating-point value
float IEEE standard 4-byte floating-point value

In addition to basic marshalling functions, where each marshalled instance of a fundamental type occupies the same number of bytes in the stream (regardless of its value), this component provides an interface for efficient marshalling of integer types. In particular, 64-bit values can be streamed as 40-, 48-, 56-, or 64-bit values, and 32-bit values can be streamed as 24- or 32-bit values. Marshalled integers are written and assumed to be in two's complement, big-endian format (i.e., network byte order). Floating-point formats are described below.

Note on Function Naming and Interface

The names and interfaces of the functions of bslx::MarshallingUtil follow a systematic fashion explained below. This makes it easier to guess the name and signature of the intended function. In what follows, buffer is always of type char * or const char * depending on whether it is used as an input or an output, and variable and value are of a type that depends on the name of the function and intended width, with variable used as an output, while value is used as an input.

Here are the get... functions for integral and floating-point scalar types:

Name Type of 'variable' Notes
---- ------------------ -----
getIntNN(variable, buffer) bsls::Types::Int64 * NN=64,56,48,40
int * NN=32,24
short * NN=16
char * NN=8
signed char * NN=8
unsigned char * NN=8
getUintNN(variable, buffer) bsls::Types::Uint64 * NN=64,56,48,40
unsigned int * NN=32,24
unsigned short * NN=16
getFloatNN(variable, buffer) double * NN=64
float * NN=32
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132

Here are the put... functions for scalar types. Note that there is no putUintNN since putIntNN applies equally to unsigned NN-bit values (through a conversion to a signed value):

Name Type of 'value' Notes
---- --------------- -----
putIntNN(buffer, value) bsls::Types::Int64 NN=64,56,48,40
int NN=32,24,16,8
putFloatNN(buffer, value) double NN=64
float NN=32

Here are the getArray... functions for integral and floating-point scalar array types:

Name Type of 'variables' Notes
---- ---------------- -----
getArrayIntNN(variables, bsls::Types::Int64 * NN=64,56,48,40
buffer, int * NN=32,24
numVariables) short * NN=16
char * NN=8
signed char * NN=8
unsigned char * NN=8
getArrayUintNN(variables, bsls::Types::Uint64 * NN=64,56,48,40
buffer, unsigned int * NN=32,24
numVariables) unsigned short * NN=16
getArrayFloatNN(variables, double * NN=64
buffer, float * NN=32
numVariables)

Finally, the putArray... functions follow. Note that this time there is an overload for unsigned types, but that the function name is still putArrayInt... for arrays of both signed and unsigned integrals:

Name Type of 'values' Notes
---- --------------- -----
putArrayIntNN(buffer, const bsls::Types::Int64 * NN=64,56,48,40
values, const bsls::Types::Uint64 * NN=64,56,48,40
numValues) const int * NN=32,24
const unsigned int * NN=32,24
const short * NN=16
const unsigned short * NN=16
const char * NN=8
const signed char * NN=8
const unsigned char * NN=8
putArrayFloatNN(buffer, const double * NN=64
values, const float * NN=32
numValues)

IEEE 754 Double-Precision Format

A double is assumed to be at least 64 bits in size. The externalized byte representation of a 64-bit floating-point value is defined to conform to the IEEE double-precision format illustrated below. If the native representation of a 64-bit floating-point value does not match this format, a conversion process to and from this format is performed. This conversion may (of course) be lossy:

sign bit 11-bit exponent 52-bit significand
/ / /
+-+-----------+----------------------------------------------------+
|s|e10......e0|m51...............................................m0|
+-+-----------+----------------------------------------------------+
LSB MSB

IEEE 754 Single-Precision Format

A float is assumed to be at least 32 bits in size. The externalized byte representation of a 32-bit floating-point value is defined to conform to the IEEE single-precision format illustrated below. If the native representation of a 32-bit floating-point value does not match this format, a conversion process to and from this format is performed. This conversion may (of course) be lossy:

sign bit 8-bit exponent 23-bit significand
/ / /
+-+--------+-----------------------+
|s|e7....e0|m22..................m0|
+-+--------+-----------------------+
LSB MSB

Usage

This section illustrates intended use of this component.

Example 1: Round-Trip Marshalling

The bslx::MarshallingUtil component can be used stand-alone to marshal a platform-neutral representation of fundamental data and arrays of fundamental data to and from a buffer. In this example, the round-trip marshalling of an int and an array of int values will be demonstrated. First, declare the buffer and the data to be marshalled:

char buffer[32];
int value = 17;
int values[] = { 1, 2, 3 };

Then, marshal all data into the buffer:

bslx::MarshallingUtil::putArrayInt32(buffer + 4, values, 3);
static void putArrayInt32(char *buffer, const int *values, int numValues)
static void putInt32(char *buffer, int value)
Definition bslx_marshallingutil.h:916

Next, declare variables to hold the values to be extracted from the buffer:

int newValue = 0;
int newValues[] = { 0, 0, 0 };

Finally, marshal the data from the buffer to these variables and confirm the round-trip marshalling was successful:

bslx::MarshallingUtil::getInt32(&newValue, buffer + 0);
bslx::MarshallingUtil::getArrayInt32(newValues, buffer + 4, 3);
assert(newValue == value);
assert(newValues[0] == values[0]);
assert(newValues[1] == values[1]);
assert(newValues[2] == values[2]);
static void getInt32(int *variable, const char *buffer)
Definition bslx_marshallingutil.h:1222
static void getArrayInt32(int *variables, const char *buffer, int numVariables)