Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bslx_marshallingutil
[Package bslx]

Support platform-independent marshalling of fundamental types. More...

Namespaces

namespace  bslx

Detailed Description

Outline
Purpose:
Support platform-independent marshalling of fundamental types.
Classes:
bslx::MarshallingUtil namespace for put/get marshalling functions
See also:
Component bslx_byteinstream, Component 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
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::putInt32(buffer + 0, value);
  bslx::MarshallingUtil::putArrayInt32(buffer + 4, values, 3);
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]);