Classes | Public Types | Static Public Member Functions

ACE_CDR Class Reference

Keep constants and some routines common to both Output and Input CDR streams. More...

#include <CDR_Base.h>

List of all members.

Classes

struct  Double
struct  Float
struct  LongDouble

Public Types

enum  {
  OCTET_SIZE = 1, SHORT_SIZE = 2, LONG_SIZE = 4, LONGLONG_SIZE = 8,
  LONGDOUBLE_SIZE = 16, OCTET_ALIGN = 1, SHORT_ALIGN = 2, LONG_ALIGN = 4,
  LONGLONG_ALIGN = 8, LONGDOUBLE_ALIGN = 8, MAX_ALIGNMENT = 8, DEFAULT_BUFSIZE = ACE_DEFAULT_CDR_BUFSIZE,
  EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX, LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK
}
enum  Byte_Order { BYTE_ORDER_BIG_ENDIAN = 0, BYTE_ORDER_LITTLE_ENDIAN = 1, BYTE_ORDER_NATIVE = ACE_CDR_BYTE_ORDER }
Basic OMG IDL Types

These types are for use in the CDR classes. The cleanest way to avoid complaints from all compilers is to define them all.

typedef bool Boolean
typedef unsigned char Octet
typedef char Char
typedef ACE_WCHAR_T WChar
typedef ACE_INT16 Short
typedef ACE_UINT16 UShort
typedef ACE_INT32 Long
typedef ACE_UINT32 ULong
typedef ACE_UINT64 ULongLong
typedef long long LongLong

Static Public Member Functions

static void swap_2 (char const *orig, char *target)
static void swap_4 (char const *orig, char *target)
static void swap_8 (char const *orig, char *target)
static void swap_16 (char const *orig, char *target)
static void swap_2_array (char const *orig, char *target, size_t length)
static void swap_4_array (char const *orig, char *target, size_t length)
static void swap_8_array (char const *orig, char *target, size_t length)
static void swap_16_array (char const *orig, char *target, size_t length)
static void mb_align (ACE_Message_Block *mb)
static size_t first_size (size_t minsize)
static size_t next_size (size_t minsize)
static int grow (ACE_Message_Block *mb, size_t minsize)
static int consolidate (ACE_Message_Block *dst, const ACE_Message_Block *src)
static size_t total_length (const ACE_Message_Block *begin, const ACE_Message_Block *end)

Detailed Description

Keep constants and some routines common to both Output and Input CDR streams.

Definition at line 62 of file CDR_Base.h.


Member Typedef Documentation

typedef bool ACE_CDR::Boolean

Definition at line 200 of file CDR_Base.h.

typedef char ACE_CDR::Char

Definition at line 202 of file CDR_Base.h.

typedef ACE_INT32 ACE_CDR::Long

Definition at line 206 of file CDR_Base.h.

typedef long long ACE_CDR::LongLong

Definition at line 223 of file CDR_Base.h.

typedef unsigned char ACE_CDR::Octet

Definition at line 201 of file CDR_Base.h.

typedef ACE_INT16 ACE_CDR::Short

Definition at line 204 of file CDR_Base.h.

typedef ACE_UINT32 ACE_CDR::ULong

Definition at line 207 of file CDR_Base.h.

Definition at line 208 of file CDR_Base.h.

typedef ACE_UINT16 ACE_CDR::UShort

Definition at line 205 of file CDR_Base.h.

typedef ACE_WCHAR_T ACE_CDR::WChar

Definition at line 203 of file CDR_Base.h.


Member Enumeration Documentation

anonymous enum
Enumerator:
OCTET_SIZE 
SHORT_SIZE 
LONG_SIZE 
LONGLONG_SIZE 
LONGDOUBLE_SIZE 
OCTET_ALIGN 
SHORT_ALIGN 
LONG_ALIGN 
LONGLONG_ALIGN 
LONGDOUBLE_ALIGN 
Note:
the CORBA LongDouble alignment requirements do not match its size...
MAX_ALIGNMENT 

Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long double", size as above).

DEFAULT_BUFSIZE 

The default buffer size.

Todo:
We want to add options to control this default value, so this constant should be read as the default default value ;-)
EXP_GROWTH_MAX 

The buffer size grows exponentially until it reaches this size; afterwards it grows linearly using the next constant

LINEAR_GROWTH_CHUNK 

Once exponential growth is ruled out the buffer size increases in chunks of this size, note that this constants have the same value right now, but it does not need to be so.

Definition at line 70 of file CDR_Base.h.

  {
    // Note that some of these get reused as part of the standard
    // binary format: unsigned is the same size as its signed cousin,
    // float is LONG_SIZE, and double is LONGLONG_SIZE.

    OCTET_SIZE = 1,
    SHORT_SIZE = 2,
    LONG_SIZE = 4,
    LONGLONG_SIZE = 8,
    LONGDOUBLE_SIZE = 16,

    OCTET_ALIGN = 1,
    SHORT_ALIGN = 2,
    LONG_ALIGN = 4,
    LONGLONG_ALIGN = 8,
    /// @note the CORBA LongDouble alignment requirements do not
    /// match its size...
    LONGDOUBLE_ALIGN = 8,

    /// Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long
    /// double", size as above).
    MAX_ALIGNMENT = 8,

    /// The default buffer size.
    /**
     * @todo We want to add options to control this
     *   default value, so this constant should be read as the default
     *   default value ;-)
     */
    DEFAULT_BUFSIZE = ACE_DEFAULT_CDR_BUFSIZE,

    /// The buffer size grows exponentially until it reaches this size;
    /// afterwards it grows linearly using the next constant
    EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX,

    /// Once exponential growth is ruled out the buffer size increases
    /// in chunks of this size, note that this constants have the same
    /// value right now, but it does not need to be so.
    LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK
  };

Defines values for the byte_order argument to ACE_OutputCDR and ACE_InputCDR.

Enumerator:
BYTE_ORDER_BIG_ENDIAN 

Use big-endian order (also known as network byte order).

BYTE_ORDER_LITTLE_ENDIAN 

Use little-endian order.

BYTE_ORDER_NATIVE 

Use whichever byte order is native to this machine.

Definition at line 118 of file CDR_Base.h.

  {
    /// Use big-endian order (also known as network byte order).
    BYTE_ORDER_BIG_ENDIAN = 0,
    /// Use little-endian order.
    BYTE_ORDER_LITTLE_ENDIAN = 1,
    /// Use whichever byte order is native to this machine.
    BYTE_ORDER_NATIVE = ACE_CDR_BYTE_ORDER
  };


Member Function Documentation

int ACE_CDR::consolidate ( ACE_Message_Block dst,
const ACE_Message_Block src 
) [static]

Copy a message block chain into a single message block, preserving the alignment of the first message block of the original stream, not the following message blocks.

Return values:
-1 Failure
0 Success.

Definition at line 553 of file CDR_Base.cpp.

{
  if (src == 0)
    return 0;

  size_t const newsize =
    ACE_CDR::first_size (ACE_CDR::total_length (src, 0)
                         + ACE_CDR::MAX_ALIGNMENT);

  if (dst->size (newsize) == -1)
    return -1;

#if !defined (ACE_CDR_IGNORE_ALIGNMENT)
  // We must copy the contents of src into the new buffer, but
  // respecting the alignment.
  ptrdiff_t srcalign =
    ptrdiff_t(src->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT;
  ptrdiff_t dstalign =
    ptrdiff_t(dst->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT;
  ptrdiff_t offset = srcalign - dstalign;
  if (offset < 0)
    offset += ACE_CDR::MAX_ALIGNMENT;
  dst->rd_ptr (static_cast<size_t> (offset));
  dst->wr_ptr (dst->rd_ptr ());
#endif /* ACE_CDR_IGNORE_ALIGNMENT */

  for (const ACE_Message_Block* i = src;
       i != 0;
       i = i->cont ())
    {
      // If the destination and source are the same, do not
      // attempt to copy the data.  Just update the write pointer.
      if (dst->wr_ptr () != i->rd_ptr ())
        dst->copy (i->rd_ptr (), i->length ());
      else
        dst->wr_ptr (i->length ());
    }
  return 0;
}

size_t ACE_CDR::first_size ( size_t  minsize  )  [inline, static]

Compute the size of the smallest buffer that can contain at least minsize bytes. To understand how a "best fit" is computed look at the algorithm in the code. Basically the buffers grow exponentially, up to a certain point, then the buffer size grows linearly. The advantage of this algorithm is that is rapidly grows to a large value, but does not explode at the end.

Definition at line 204 of file CDR_Base.inl.

{
  if (minsize == 0)
    return ACE_CDR::DEFAULT_BUFSIZE;

  size_t newsize = ACE_CDR::DEFAULT_BUFSIZE;
  while (newsize < minsize)
    {
      if (newsize < ACE_CDR::EXP_GROWTH_MAX)
        {
          // We grow exponentially at the beginning, this is fast and
          // reduces the number of allocations.

          // Quickly multiply by two using a bit shift.  This is
          // guaranteed to work since the variable is an unsigned
          // integer.
          newsize <<= 1;
        }
      else
        {
          // but continuing with exponential growth can result in over
          // allocations and easily yield an allocation failure.
          // So we grow linearly when the buffer is too big.
          newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
        }
    }
  return newsize;
}

int ACE_CDR::grow ( ACE_Message_Block mb,
size_t  minsize 
) [static]

Increase the capacity of mb to contain at least minsize bytes. If minsize is zero the size is increased by an amount at least large enough to contain any of the basic IDL types.

Return values:
-1 Failure
0 Success.

Definition at line 503 of file CDR_Base.cpp.

{
  size_t newsize =
    ACE_CDR::first_size (minsize + ACE_CDR::MAX_ALIGNMENT);

  if (newsize <= mb->size ())
    return 0;

  ACE_Data_Block *db =
    mb->data_block ()->clone_nocopy (0, newsize);

  if (db == 0)
    return -1;

  // Do the equivalent of ACE_CDR::mb_align() here to avoid having
  // to allocate an ACE_Message_Block on the stack thereby avoiding
  // the manipulation of the data blocks reference count
  size_t mb_len = mb->length ();
  char *start = ACE_ptr_align_binary (db->base (),
                                      ACE_CDR::MAX_ALIGNMENT);

  ACE_OS::memcpy (start, mb->rd_ptr (), mb_len);
  mb->data_block (db);

  // Setting the data block on the mb resets the read and write
  // pointers back to the beginning.  We must set the rd_ptr to the
  // aligned start and adjust the write pointer to the end
  mb->rd_ptr (start);
  mb->wr_ptr (start + mb_len);

  // Remove the DONT_DELETE flags from mb
  mb->clr_self_flags (ACE_Message_Block::DONT_DELETE);

  return 0;
}

void ACE_CDR::mb_align ( ACE_Message_Block mb  )  [static]

Align the message block to ACE_CDR::MAX_ALIGNMENT, set by the CORBA spec at 8 bytes.

Definition at line 490 of file CDR_Base.cpp.

{
#if !defined (ACE_CDR_IGNORE_ALIGNMENT)
  char * const start = ACE_ptr_align_binary (mb->base (),
                                             ACE_CDR::MAX_ALIGNMENT);
#else
  char * const start = mb->base ();
#endif /* ACE_CDR_IGNORE_ALIGNMENT */
  mb->rd_ptr (start);
  mb->wr_ptr (start);
}

size_t ACE_CDR::next_size ( size_t  minsize  )  [inline, static]

Compute not the smallest, but the second smallest buffer that will fir minsize bytes.

Definition at line 234 of file CDR_Base.inl.

{
  size_t newsize = ACE_CDR::first_size (minsize);

  if (newsize == minsize)
    {
      // If necessary increment the size
      if (newsize < ACE_CDR::EXP_GROWTH_MAX)
        // Quickly multiply by two using a bit shift.  This is
        // guaranteed to work since the variable is an unsigned
        // integer.
        newsize <<= 1;
      else
        newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
    }

  return newsize;
}

void ACE_CDR::swap_16 ( char const *  orig,
char *  target 
) [inline, static]

Definition at line 197 of file CDR_Base.inl.

{
  swap_8 (orig + 8, target);
  swap_8 (orig, target + 8);
}

void ACE_CDR::swap_16_array ( char const *  orig,
char *  target,
size_t  length 
) [static]

Definition at line 476 of file CDR_Base.cpp.

{
  // ACE_ASSERT(n > 0); The caller checks that n > 0

  char const * const end = orig + 16*n;
  while (orig < end)
    {
      swap_16 (orig, target);
      orig += 16;
      target += 16;
    }
}

void ACE_CDR::swap_2 ( char const *  orig,
char *  target 
) [inline, static]

Do byte swapping for each basic IDL type size. There exist only routines to put byte, halfword (2 bytes), word (4 bytes), doubleword (8 bytes) and quadword (16 byte); because those are the IDL basic type sizes.

Definition at line 66 of file CDR_Base.inl.

{
#if defined (ACE_HAS_INTRINSIC_BYTESWAP)
  // Take advantage of MSVC++ compiler intrinsic byte swapping
  // function.
  *reinterpret_cast<unsigned short *> (target) =
    _byteswap_ushort (*reinterpret_cast<unsigned short const *> (orig));
#elif defined (ACE_HAS_BSWAP16)
  *reinterpret_cast<uint16_t *> (target) =
    bswap16 (*reinterpret_cast<uint16_t const *> (orig));
#elif defined (ACE_HAS_BSWAP_16)
  *reinterpret_cast<uint16_t *> (target) =
    bswap_16 (*reinterpret_cast<uint16_t const *> (orig));
#elif defined(ACE_HAS_INTEL_ASSEMBLY)
  unsigned short a =
    *reinterpret_cast<const unsigned short*> (orig);
  asm( "rolw $8, %0" : "=r" (a) : "0" (a) );
  *reinterpret_cast<unsigned short*> (target) = a;
#elif defined (ACE_HAS_PENTIUM) \
       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
  __asm mov ebx, orig;
  __asm mov ecx, target;
  __asm mov ax, [ebx];
  __asm rol ax, 8;
  __asm mov [ecx], ax;
#else
  register ACE_UINT16 usrc = * reinterpret_cast<const ACE_UINT16*> (orig);
  register ACE_UINT16* udst = reinterpret_cast<ACE_UINT16*> (target);
  *udst = (usrc << 8) | (usrc >> 8);
#endif /* ACE_HAS_PENTIUM */
}

void ACE_CDR::swap_2_array ( char const *  orig,
char *  target,
size_t  length 
) [static]

Definition at line 27 of file CDR_Base.cpp.

{
  // ACE_ASSERT(n > 0); The caller checks that n > 0

  // We pretend that AMD64/GNU G++ systems have a Pentium CPU to
  // take advantage of the inline assembly implementation.

  // Later, we try to read in 32 or 64 bit chunks,
  // so make sure we don't do that for unaligned addresses.
#if ACE_SIZEOF_LONG == 8 && \
    !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__))
  char const * const o8 = ACE_ptr_align_binary (orig, 8);
  while (orig < o8 && n > 0)
    {
      ACE_CDR::swap_2 (orig, target);
      orig += 2;
      target += 2;
      --n;
    }
#else
  char const * const o4 = ACE_ptr_align_binary (orig, 4);
  // this is an _if_, not a _while_. The mistmatch can only be by 2.
  if (orig != o4)
    {
      ACE_CDR::swap_2 (orig, target);
      orig += 2;
      target += 2;
      --n;
    }
#endif
  if (n == 0)
    return;

  //
  // Loop unrolling. Here be dragons.
  //

  // (n & (~3)) is the greatest multiple of 4 not bigger than n.
  // In the while loop ahead, orig will move over the array by 8 byte
  // increments (4 elements of 2 bytes).
  // end marks our barrier for not falling outside.
  char const * const end = orig + 2 * (n & (~3));

  // See if we're aligned for writting in 64 or 32 bit chunks...
#if ACE_SIZEOF_LONG == 8 && \
    !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__))
  if (target == ACE_ptr_align_binary (target, 8))
#else
  if (target == ACE_ptr_align_binary (target, 4))
#endif
    {
      while (orig < end)
        {
#if defined (ACE_HAS_INTEL_ASSEMBLY)
          unsigned int a =
            * reinterpret_cast<const unsigned int*> (orig);
          unsigned int b =
            * reinterpret_cast<const unsigned int*> (orig + 4);
          asm ( "bswap %1"      : "=r" (a) : "0" (a) );
          asm ( "bswap %1"      : "=r" (b) : "0" (b) );
          asm ( "rol $16, %1"   : "=r" (a) : "0" (a) );
          asm ( "rol $16, %1"   : "=r" (b) : "0" (b) );
          * reinterpret_cast<unsigned int*> (target) = a;
          * reinterpret_cast<unsigned int*> (target + 4) = b;
#elif defined(ACE_HAS_PENTIUM) \
      && (defined(_MSC_VER) || defined(__BORLANDC__)) \
      && !defined(ACE_LACKS_INLINE_ASSEMBLY)
          __asm mov ecx, orig;
          __asm mov edx, target;
          __asm mov eax, [ecx];
          __asm mov ebx, 4[ecx];
          __asm bswap eax;
          __asm bswap ebx;
          __asm rol eax, 16;
          __asm rol ebx, 16;
          __asm mov [edx], eax;
          __asm mov 4[edx], ebx;
#elif ACE_SIZEOF_LONG == 8
          // 64 bit architecture.
          register unsigned long a =
            * reinterpret_cast<const unsigned long*> (orig);

          register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8;
          register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8;

          a = (a1 | a2);

          * reinterpret_cast<unsigned long*> (target) = a;
#else
          register ACE_UINT32 a =
            * reinterpret_cast<const ACE_UINT32*> (orig);
          register ACE_UINT32 b =
            * reinterpret_cast<const ACE_UINT32*> (orig + 4);

          register ACE_UINT32 a1 = (a & 0x00ff00ffU) << 8;
          register ACE_UINT32 b1 = (b & 0x00ff00ffU) << 8;
          register ACE_UINT32 a2 = (a & 0xff00ff00U) >> 8;
          register ACE_UINT32 b2 = (b & 0xff00ff00U) >> 8;

          a = (a1 | a2);
          b = (b1 | b2);

          * reinterpret_cast<ACE_UINT32*> (target) = a;
          * reinterpret_cast<ACE_UINT32*> (target + 4) = b;
#endif
          orig += 8;
          target += 8;
        }
    }
  else
    {
      // We're out of luck. We have to write in 2 byte chunks.
      while (orig < end)
        {
#if defined (ACE_HAS_INTEL_ASSEMBLY)
          unsigned int a =
            * reinterpret_cast<const unsigned int*> (orig);
          unsigned int b =
            * reinterpret_cast<const unsigned int*> (orig + 4);
          asm ( "bswap %1" : "=r" (a) : "0" (a) );
          asm ( "bswap %1" : "=r" (b) : "0" (b) );
          // We're little endian.
          * reinterpret_cast<unsigned short*> (target + 2)
              = (unsigned short) (a & 0xffff);
          * reinterpret_cast<unsigned short*> (target + 6)
              = (unsigned short) (b & 0xffff);
          asm ( "shrl $16, %1" : "=r" (a) : "0" (a) );
          asm ( "shrl $16, %1" : "=r" (b) : "0" (b) );
          * reinterpret_cast<unsigned short*> (target + 0)
              = (unsigned short) (a & 0xffff);
          * reinterpret_cast<unsigned short*> (target + 4)
              = (unsigned short) (b & 0xffff);
#elif defined (ACE_HAS_PENTIUM) \
      && (defined (_MSC_VER) || defined (__BORLANDC__)) \
      && !defined (ACE_LACKS_INLINE_ASSEMBLY)
          __asm mov ecx, orig;
          __asm mov edx, target;
          __asm mov eax, [ecx];
          __asm mov ebx, 4[ecx];
          __asm bswap eax;
          __asm bswap ebx;
          // We're little endian.
          __asm mov 2[edx], ax;
          __asm mov 6[edx], bx;
          __asm shr eax, 16;
          __asm shr ebx, 16;
          __asm mov 0[edx], ax;
          __asm mov 4[edx], bx;
#elif ACE_SIZEOF_LONG == 8
          // 64 bit architecture.
          register unsigned long a =
            * reinterpret_cast<const unsigned long*> (orig);

          register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8;
          register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8;

          a = (a1 | a2);

          ACE_UINT16 b1 = static_cast<ACE_UINT16> (a >> 48);
          ACE_UINT16 b2 = static_cast<ACE_UINT16> ((a >> 32) & 0xffff);
          ACE_UINT16 b3 = static_cast<ACE_UINT16> ((a >> 16) & 0xffff);
          ACE_UINT16 b4 = static_cast<ACE_UINT16> (a & 0xffff);

#if defined(ACE_LITTLE_ENDIAN)
          * reinterpret_cast<ACE_UINT16*> (target) = b4;
          * reinterpret_cast<ACE_UINT16*> (target + 2) = b3;
          * reinterpret_cast<ACE_UINT16*> (target + 4) = b2;
          * reinterpret_cast<ACE_UINT16*> (target + 6) = b1;
#else
          * reinterpret_cast<ACE_UINT16*> (target) = b1;
          * reinterpret_cast<ACE_UINT16*> (target + 2) = b2;
          * reinterpret_cast<ACE_UINT16*> (target + 4) = b3;
          * reinterpret_cast<ACE_UINT16*> (target + 6) = b4;
#endif
#else
          register ACE_UINT32 a =
            * reinterpret_cast<const ACE_UINT32*> (orig);
          register ACE_UINT32 b =
            * reinterpret_cast<const ACE_UINT32*> (orig + 4);

          register ACE_UINT32 a1 = (a & 0x00ff00ff) << 8;
          register ACE_UINT32 b1 = (b & 0x00ff00ff) << 8;
          register ACE_UINT32 a2 = (a & 0xff00ff00) >> 8;
          register ACE_UINT32 b2 = (b & 0xff00ff00) >> 8;

          a = (a1 | a2);
          b = (b1 | b2);

          ACE_UINT32 c1 = static_cast<ACE_UINT16> (a >> 16);
          ACE_UINT32 c2 = static_cast<ACE_UINT16> (a & 0xffff);
          ACE_UINT32 c3 = static_cast<ACE_UINT16> (b >> 16);
          ACE_UINT32 c4 = static_cast<ACE_UINT16> (b & 0xffff);

#if defined(ACE_LITTLE_ENDIAN)
          * reinterpret_cast<ACE_UINT16*> (target) = c2;
          * reinterpret_cast<ACE_UINT16*> (target + 2) = c1;
          * reinterpret_cast<ACE_UINT16*> (target + 4) = c4;
          * reinterpret_cast<ACE_UINT16*> (target + 6) = c3;
#else
          * reinterpret_cast<ACE_UINT16*> (target) = c1;
          * reinterpret_cast<ACE_UINT16*> (target + 2) = c2;
          * reinterpret_cast<ACE_UINT16*> (target + 4) = c3;
          * reinterpret_cast<ACE_UINT16*> (target + 6) = c4;
#endif
#endif

          orig += 8;
          target += 8;
        }
    }

  // (n & 3) == (n % 4).
  switch (n&3) {
  case 3:
    ACE_CDR::swap_2 (orig, target);
    orig += 2;
    target += 2;
  case 2:
    ACE_CDR::swap_2 (orig, target);
    orig += 2;
    target += 2;
  case 1:
    ACE_CDR::swap_2 (orig, target);
  }
}

void ACE_CDR::swap_4 ( char const *  orig,
char *  target 
) [inline, static]

Definition at line 100 of file CDR_Base.inl.

{
#if defined (ACE_HAS_INTRINSIC_BYTESWAP)
  // Take advantage of MSVC++ compiler intrinsic byte swapping
  // function.
  *reinterpret_cast<unsigned long *> (target) =
    _byteswap_ulong (*reinterpret_cast<unsigned long const *> (orig));
#elif defined (ACE_HAS_BSWAP32)
  *reinterpret_cast<uint32_t *> (target) =
    bswap32 (*reinterpret_cast<uint32_t const *> (orig));
#elif defined (ACE_HAS_BSWAP_32)
  *reinterpret_cast<uint32_t *> (target) =
    bswap_32 (*reinterpret_cast<uint32_t const *> (orig));
#elif defined(ACE_HAS_INTEL_ASSEMBLY)
  // We have ACE_HAS_PENTIUM, so we know the sizeof's.
  register unsigned int j =
    *reinterpret_cast<const unsigned int*> (orig);
  asm ("bswap %1" : "=r" (j) : "0" (j));
  *reinterpret_cast<unsigned int*> (target) = j;
#elif defined(ACE_HAS_PENTIUM) \
      && (defined(_MSC_VER) || defined(__BORLANDC__)) \
      && !defined(ACE_LACKS_INLINE_ASSEMBLY)
  __asm mov ebx, orig;
  __asm mov ecx, target;
  __asm mov eax, [ebx];
  __asm bswap eax;
  __asm mov [ecx], eax;
#else
  register ACE_UINT32 x = * reinterpret_cast<const ACE_UINT32*> (orig);
  x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
  * reinterpret_cast<ACE_UINT32*> (target) = x;
#endif /* ACE_HAS_INTRINSIC_BYTESWAP */
}

void ACE_CDR::swap_4_array ( char const *  orig,
char *  target,
size_t  length 
) [static]

Definition at line 254 of file CDR_Base.cpp.

{
  // ACE_ASSERT (n > 0); The caller checks that n > 0

#if ACE_SIZEOF_LONG == 8
  // Later, we read from *orig in 64 bit chunks,
  // so make sure we don't generate unaligned readings.
  char const * const o8 = ACE_ptr_align_binary (orig, 8);
  // The mismatch can only be by 4.
  if (orig != o8)
    {
      ACE_CDR::swap_4 (orig, target);
      orig += 4;
      target += 4;
      --n;
    }
#endif  /* ACE_SIZEOF_LONG == 8 */

  if (n == 0)
    return;

  //
  // Loop unrolling. Here be dragons.
  //

  // (n & (~3)) is the greatest multiple of 4 not bigger than n.
  // In the while loop, orig will move over the array by 16 byte
  // increments (4 elements of 4 bytes).
  // ends marks our barrier for not falling outside.
  char const * const end = orig + 4 * (n & (~3));

#if ACE_SIZEOF_LONG == 8
  // 64 bits architecture.
  // See if we can write in 8 byte chunks.
  if (target == ACE_ptr_align_binary (target, 8))
    {
      while (orig < end)
        {
          register unsigned long a =
            * reinterpret_cast<const long*> (orig);
          register unsigned long b =
            * reinterpret_cast<const long*> (orig + 8);

#if defined(ACE_HAS_INTEL_ASSEMBLY)
          asm ("bswapq %1" : "=r" (a) : "0" (a));
          asm ("bswapq %1" : "=r" (b) : "0" (b));
          asm ("rol $32, %1" : "=r" (a) : "0" (a));
          asm ("rol $32, %1" : "=r" (b) : "0" (b));
#else
          register unsigned long a84 = (a & 0x000000ff000000ffL) << 24;
          register unsigned long b84 = (b & 0x000000ff000000ffL) << 24;
          register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8;
          register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8;
          register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8;
          register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8;
          register unsigned long a51 = (a & 0xff000000ff000000L) >> 24;
          register unsigned long b51 = (b & 0xff000000ff000000L) >> 24;

          a = (a84 | a73 | a62 | a51);
          b = (b84 | b73 | b62 | b51);
#endif

          * reinterpret_cast<long*> (target) = a;
          * reinterpret_cast<long*> (target + 8) = b;

          orig += 16;
          target += 16;
        }
    }
  else
    {
      // We are out of luck, we have to write in 4 byte chunks.
      while (orig < end)
        {
          register unsigned long a =
            * reinterpret_cast<const long*> (orig);
          register unsigned long b =
            * reinterpret_cast<const long*> (orig + 8);

#if defined(ACE_HAS_INTEL_ASSEMBLY)
          asm ("bswapq %1" : "=r" (a) : "0" (a));
          asm ("bswapq %1" : "=r" (b) : "0" (b));
          asm ("rol $32, %1" : "=r" (a) : "0" (a));
          asm ("rol $32, %1" : "=r" (b) : "0" (b));
#else
          register unsigned long a84 = (a & 0x000000ff000000ffL) << 24;
          register unsigned long b84 = (b & 0x000000ff000000ffL) << 24;
          register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8;
          register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8;
          register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8;
          register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8;
          register unsigned long a51 = (a & 0xff000000ff000000L) >> 24;
          register unsigned long b51 = (b & 0xff000000ff000000L) >> 24;

          a = (a84 | a73 | a62 | a51);
          b = (b84 | b73 | b62 | b51);
#endif

          ACE_UINT32 c1 = static_cast<ACE_UINT32> (a >> 32);
          ACE_UINT32 c2 = static_cast<ACE_UINT32> (a & 0xffffffff);
          ACE_UINT32 c3 = static_cast<ACE_UINT32> (b >> 32);
          ACE_UINT32 c4 = static_cast<ACE_UINT32> (b & 0xffffffff);

#if defined (ACE_LITTLE_ENDIAN)
          * reinterpret_cast<ACE_UINT32*> (target + 0) = c2;
          * reinterpret_cast<ACE_UINT32*> (target + 4) = c1;
          * reinterpret_cast<ACE_UINT32*> (target + 8) = c4;
          * reinterpret_cast<ACE_UINT32*> (target + 12) = c3;
#else
          * reinterpret_cast<ACE_UINT32*> (target + 0) = c1;
          * reinterpret_cast<ACE_UINT32*> (target + 4) = c2;
          * reinterpret_cast<ACE_UINT32*> (target + 8) = c3;
          * reinterpret_cast<ACE_UINT32*> (target + 12) = c4;
#endif
          orig += 16;
          target += 16;
        }
    }

#else  /* ACE_SIZEOF_LONG != 8 */

  while (orig < end)
    {
#if defined (ACE_HAS_PENTIUM) && defined (__GNUG__)
      register unsigned int a =
        *reinterpret_cast<const unsigned int*> (orig);
      register unsigned int b =
        *reinterpret_cast<const unsigned int*> (orig + 4);
      register unsigned int c =
        *reinterpret_cast<const unsigned int*> (orig + 8);
      register unsigned int d =
        *reinterpret_cast<const unsigned int*> (orig + 12);

      asm ("bswap %1" : "=r" (a) : "0" (a));
      asm ("bswap %1" : "=r" (b) : "0" (b));
      asm ("bswap %1" : "=r" (c) : "0" (c));
      asm ("bswap %1" : "=r" (d) : "0" (d));

      *reinterpret_cast<unsigned int*> (target) = a;
      *reinterpret_cast<unsigned int*> (target + 4) = b;
      *reinterpret_cast<unsigned int*> (target + 8) = c;
      *reinterpret_cast<unsigned int*> (target + 12) = d;
#elif defined (ACE_HAS_PENTIUM) \
      && (defined (_MSC_VER) || defined (__BORLANDC__)) \
      && !defined (ACE_LACKS_INLINE_ASSEMBLY)
      __asm mov eax, orig
      __asm mov esi, target
      __asm mov edx, [eax]
      __asm mov ecx, 4[eax]
      __asm mov ebx, 8[eax]
      __asm mov eax, 12[eax]
      __asm bswap edx
      __asm bswap ecx
      __asm bswap ebx
      __asm bswap eax
      __asm mov [esi], edx
      __asm mov 4[esi], ecx
      __asm mov 8[esi], ebx
      __asm mov 12[esi], eax
#else
      register ACE_UINT32 a =
        * reinterpret_cast<const ACE_UINT32*> (orig);
      register ACE_UINT32 b =
        * reinterpret_cast<const ACE_UINT32*> (orig + 4);
      register ACE_UINT32 c =
        * reinterpret_cast<const ACE_UINT32*> (orig + 8);
      register ACE_UINT32 d =
        * reinterpret_cast<const ACE_UINT32*> (orig + 12);

      // Expect the optimizer reordering this A LOT.
      // We leave it this way for clarity.
      a = (a << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8) | (a >> 24);
      b = (b << 24) | ((b & 0xff00) << 8) | ((b & 0xff0000) >> 8) | (b >> 24);
      c = (c << 24) | ((c & 0xff00) << 8) | ((c & 0xff0000) >> 8) | (c >> 24);
      d = (d << 24) | ((d & 0xff00) << 8) | ((d & 0xff0000) >> 8) | (d >> 24);

      * reinterpret_cast<ACE_UINT32*> (target) = a;
      * reinterpret_cast<ACE_UINT32*> (target + 4) = b;
      * reinterpret_cast<ACE_UINT32*> (target + 8) = c;
      * reinterpret_cast<ACE_UINT32*> (target + 12) = d;
#endif

      orig += 16;
      target += 16;
    }

#endif /* ACE_SIZEOF_LONG == 8 */

  // (n & 3) == (n % 4).
  switch (n & 3) {
  case 3:
    ACE_CDR::swap_4 (orig, target);
    orig += 4;
    target += 4;
  case 2:
    ACE_CDR::swap_4 (orig, target);
    orig += 4;
    target += 4;
  case 1:
    ACE_CDR::swap_4 (orig, target);
  }
}

void ACE_CDR::swap_8 ( char const *  orig,
char *  target 
) [inline, static]

Definition at line 135 of file CDR_Base.inl.

{
#if defined (ACE_HAS_INTRINSIC_BYTESWAP)
  // Take advantage of MSVC++ compiler intrinsic byte swapping
  // function.
  *reinterpret_cast<unsigned __int64 *> (target) =
    _byteswap_uint64 (*reinterpret_cast<unsigned __int64 const *> (orig));
#elif defined (ACE_HAS_BSWAP64)
  *reinterpret_cast<uint64_t *> (target) =
    bswap64 (*reinterpret_cast<uint64_t const *> (orig));
#elif defined (ACE_HAS_BSWAP_64)
  *reinterpret_cast<uint64_t *> (target) =
    bswap_64 (*reinterpret_cast<uint64_t const *> (orig));
#elif (defined (__amd64__) || defined (__x86_64__)) && defined(__GNUG__)
  register unsigned long x =
    * reinterpret_cast<const unsigned long*> (orig);
  asm ("bswapq %1" : "=r" (x) : "0" (x));
  *reinterpret_cast<unsigned long*> (target) = x;
#elif defined(ACE_HAS_PENTIUM) && defined(__GNUG__)
  register unsigned int i =
    *reinterpret_cast<const unsigned int*> (orig);
  register unsigned int j =
    *reinterpret_cast<const unsigned int*> (orig + 4);
  asm ("bswap %1" : "=r" (i) : "0" (i));
  asm ("bswap %1" : "=r" (j) : "0" (j));
  *reinterpret_cast<unsigned int*> (target + 4) = i;
  *reinterpret_cast<unsigned int*> (target) = j;
#elif defined(ACE_HAS_PENTIUM) \
      && (defined(_MSC_VER) || defined(__BORLANDC__)) \
      && !defined(ACE_LACKS_INLINE_ASSEMBLY)
  __asm mov ecx, orig;
  __asm mov edx, target;
  __asm mov eax, [ecx];
  __asm mov ebx, 4[ecx];
  __asm bswap eax;
  __asm bswap ebx;
  __asm mov 4[edx], eax;
  __asm mov [edx], ebx;
#elif ACE_SIZEOF_LONG == 8
  // 64 bit architecture.
  register unsigned long x =
    * reinterpret_cast<const unsigned long*> (orig);
  register unsigned long x84 = (x & 0x000000ff000000ffUL) << 24;
  register unsigned long x73 = (x & 0x0000ff000000ff00UL) << 8;
  register unsigned long x62 = (x & 0x00ff000000ff0000UL) >> 8;
  register unsigned long x51 = (x & 0xff000000ff000000UL) >> 24;
  x = (x84 | x73 | x62 | x51);
  x = (x << 32) | (x >> 32);
  *reinterpret_cast<unsigned long*> (target) = x;
#else
  register ACE_UINT32 x =
    * reinterpret_cast<const ACE_UINT32*> (orig);
  register ACE_UINT32 y =
    * reinterpret_cast<const ACE_UINT32*> (orig + 4);
  x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
  y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24);
  * reinterpret_cast<ACE_UINT32*> (target) = y;
  * reinterpret_cast<ACE_UINT32*> (target + 4) = x;
#endif /* ACE_HAS_INTRINSIC_BYTESWAP */
}

void ACE_CDR::swap_8_array ( char const *  orig,
char *  target,
size_t  length 
) [static]

Definition at line 462 of file CDR_Base.cpp.

{
  // ACE_ASSERT(n > 0); The caller checks that n > 0

  char const * const end = orig + 8*n;
  while (orig < end)
    {
      swap_8 (orig, target);
      orig += 8;
      target += 8;
    }
}

size_t ACE_CDR::total_length ( const ACE_Message_Block begin,
const ACE_Message_Block end 
) [static]

Definition at line 540 of file CDR_Base.cpp.

{
  size_t l = 0;
  // Compute the total size.
  for (const ACE_Message_Block *i = begin;
       i != end;
       i = i->cont ())
    l += i->length ();
  return l;
}


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines