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.

Public Types

 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
 The default buffer size.
 EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX
 LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK
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
}
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 void 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)

Classes

struct  Double
struct  Float
struct  LongDouble


Detailed Description

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

Definition at line 52 of file CDR_Base.h.


Member Typedef Documentation

typedef bool ACE_CDR::Boolean

Definition at line 170 of file CDR_Base.h.

typedef char ACE_CDR::Char

Definition at line 172 of file CDR_Base.h.

typedef ACE_INT32 ACE_CDR::Long

Definition at line 176 of file CDR_Base.h.

typedef long long ACE_CDR::LongLong

Definition at line 194 of file CDR_Base.h.

typedef unsigned char ACE_CDR::Octet

Definition at line 171 of file CDR_Base.h.

typedef ACE_INT16 ACE_CDR::Short

Definition at line 174 of file CDR_Base.h.

typedef ACE_UINT32 ACE_CDR::ULong

Definition at line 177 of file CDR_Base.h.

typedef ACE_UINT64 ACE_CDR::ULongLong

Definition at line 178 of file CDR_Base.h.

typedef ACE_UINT16 ACE_CDR::UShort

Definition at line 175 of file CDR_Base.h.

typedef ACE_WCHAR_T ACE_CDR::WChar

Definition at line 173 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. "CDRLong 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 60 of file CDR_Base.h.

00061   {
00062     // Note that some of these get reused as part of the standard
00063     // binary format: unsigned is the same size as its signed cousin,
00064     // float is LONG_SIZE, and double is LONGLONG_SIZE.
00065 
00066     OCTET_SIZE = 1,
00067     SHORT_SIZE = 2,
00068     LONG_SIZE = 4,
00069     LONGLONG_SIZE = 8,
00070     LONGDOUBLE_SIZE = 16,
00071 
00072     OCTET_ALIGN = 1,
00073     SHORT_ALIGN = 2,
00074     LONG_ALIGN = 4,
00075     LONGLONG_ALIGN = 8,
00076     /// @note the CORBA LongDouble alignment requirements do not
00077     /// match its size...
00078     LONGDOUBLE_ALIGN = 8,
00079 
00080     /// Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long
00081     /// double", size as above).
00082     MAX_ALIGNMENT = 8,
00083 
00084     /// The default buffer size.
00085     /**
00086      * @todo We want to add options to control this
00087      *   default value, so this constant should be read as the default
00088      *   default value ;-)
00089      */
00090     DEFAULT_BUFSIZE = ACE_DEFAULT_CDR_BUFSIZE,
00091 
00092     /// The buffer size grows exponentially until it reaches this size;
00093     /// afterwards it grows linearly using the next constant
00094     EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX,
00095 
00096     /// Once exponential growth is ruled out the buffer size increases
00097     /// in chunks of this size, note that this constants have the same
00098     /// value right now, but it does not need to be so.
00099     LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK
00100   };


Member Function Documentation

void 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.

Definition at line 553 of file CDR_Base.cpp.

References ACE_Message_Block::copy(), first_size(), MAX_ALIGNMENT, ACE_Message_Block::rd_ptr(), ACE_Message_Block::size(), total_length(), and ACE_Message_Block::wr_ptr().

Referenced by ACE_InputCDR::reset().

00555 {
00556   if (src == 0)
00557     return;
00558 
00559   size_t newsize =
00560     ACE_CDR::first_size (ACE_CDR::total_length (src, 0)
00561                          + ACE_CDR::MAX_ALIGNMENT);
00562   dst->size (newsize);
00563 
00564 #if !defined (ACE_CDR_IGNORE_ALIGNMENT)
00565   // We must copy the contents of <src> into the new buffer, but
00566   // respecting the alignment.
00567   ptrdiff_t srcalign =
00568     ptrdiff_t(src->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT;
00569   ptrdiff_t dstalign =
00570     ptrdiff_t(dst->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT;
00571   ptrdiff_t offset = srcalign - dstalign;
00572   if (offset < 0)
00573     offset += ACE_CDR::MAX_ALIGNMENT;
00574   dst->rd_ptr (static_cast<size_t> (offset));
00575   dst->wr_ptr (dst->rd_ptr ());
00576 #endif /* ACE_CDR_IGNORE_ALIGNMENT */
00577 
00578   for (const ACE_Message_Block* i = src;
00579        i != 0;
00580        i = i->cont ())
00581     {
00582       // If the destination and source are the same, do not
00583       // attempt to copy the data.  Just update the write pointer.
00584       if (dst->wr_ptr () != i->rd_ptr ())
00585         dst->copy (i->rd_ptr (), i->length ());
00586       else
00587         dst->wr_ptr (i->length ());
00588     }
00589 }

ACE_INLINE size_t ACE_CDR::first_size ( size_t  minsize  )  [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.

References DEFAULT_BUFSIZE, EXP_GROWTH_MAX, and LINEAR_GROWTH_CHUNK.

Referenced by ACE_OutputCDR::consolidate(), consolidate(), grow(), and next_size().

00205 {
00206   if (minsize == 0)
00207     return ACE_CDR::DEFAULT_BUFSIZE;
00208 
00209   size_t newsize = ACE_CDR::DEFAULT_BUFSIZE;
00210   while (newsize < minsize)
00211     {
00212       if (newsize < ACE_CDR::EXP_GROWTH_MAX)
00213         {
00214           // We grow exponentially at the beginning, this is fast and
00215           // reduces the number of allocations.
00216 
00217           // Quickly multiply by two using a bit shift.  This is
00218           // guaranteed to work since the variable is an unsigned
00219           // integer.
00220           newsize <<= 1;
00221         }
00222       else
00223         {
00224           // but continuing with exponential growth can result in over
00225           // allocations and easily yield an allocation failure.
00226           // So we grow linearly when the buffer is too big.
00227           newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
00228         }
00229     }
00230   return newsize;
00231 }

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.

References ACE_ptr_align_binary(), ACE_Data_Block::base(), ACE_Data_Block::clone_nocopy(), ACE_Message_Block::clr_self_flags(), ACE_Message_Block::data_block(), ACE_Message_Block::DONT_DELETE, first_size(), ACE_Message_Block::length(), MAX_ALIGNMENT, ACE_OS::memcpy(), ACE_Message_Block::rd_ptr(), and ACE_Message_Block::wr_ptr().

Referenced by ACE_InputCDR::grow().

00504 {
00505   size_t newsize =
00506     ACE_CDR::first_size (minsize + ACE_CDR::MAX_ALIGNMENT);
00507 
00508   if (newsize <= mb->size ())
00509     return 0;
00510 
00511   ACE_Data_Block *db =
00512     mb->data_block ()->clone_nocopy (0, newsize);
00513 
00514   if (db == 0)
00515     return -1;
00516 
00517   // Do the equivalent of ACE_CDR::mb_align() here to avoid having
00518   // to allocate an ACE_Message_Block on the stack thereby avoiding
00519   // the manipulation of the data blocks reference count
00520   size_t mb_len = mb->length ();
00521   char *start = ACE_ptr_align_binary (db->base (),
00522                                       ACE_CDR::MAX_ALIGNMENT);
00523 
00524   ACE_OS::memcpy (start, mb->rd_ptr (), mb_len);
00525   mb->data_block (db);
00526 
00527   // Setting the data block on the mb resets the read and write
00528   // pointers back to the beginning.  We must set the rd_ptr to the
00529   // aligned start and adjust the write pointer to the end
00530   mb->rd_ptr (start);
00531   mb->wr_ptr (start + mb_len);
00532 
00533   // Remove the DONT_DELETE flags from mb
00534   mb->clr_self_flags (ACE_Message_Block::DONT_DELETE);
00535 
00536   return 0;
00537 }

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.

References ACE_ptr_align_binary(), ACE_Message_Block::base(), MAX_ALIGNMENT, ACE_Message_Block::rd_ptr(), and ACE_Message_Block::wr_ptr().

Referenced by ACE_InputCDR::ACE_InputCDR(), ACE_OutputCDR::ACE_OutputCDR(), ACE_InputCDR::clone_from(), ACE_InputCDR::grow(), ACE_OutputCDR::reset(), and ACE_InputCDR::steal_contents().

00491 {
00492 #if !defined (ACE_CDR_IGNORE_ALIGNMENT)
00493   char * const start = ACE_ptr_align_binary (mb->base (),
00494                                              ACE_CDR::MAX_ALIGNMENT);
00495 #else
00496   char * const start = mb->base ();
00497 #endif /* ACE_CDR_IGNORE_ALIGNMENT */
00498   mb->rd_ptr (start);
00499   mb->wr_ptr (start);
00500 }

ACE_INLINE size_t ACE_CDR::next_size ( size_t  minsize  )  [static]

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

Definition at line 234 of file CDR_Base.inl.

References EXP_GROWTH_MAX, first_size(), and LINEAR_GROWTH_CHUNK.

Referenced by ACE_OutputCDR::grow_and_adjust().

00235 {
00236   size_t newsize = ACE_CDR::first_size (minsize);
00237 
00238   if (newsize == minsize)
00239     {
00240       // If necessary increment the size
00241       if (newsize < ACE_CDR::EXP_GROWTH_MAX)
00242         // Quickly multiply by two using a bit shift.  This is
00243         // guaranteed to work since the variable is an unsigned
00244         // integer.
00245         newsize <<= 1;
00246       else
00247         newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
00248     }
00249 
00250   return newsize;
00251 }

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

Definition at line 197 of file CDR_Base.inl.

References swap_8().

Referenced by ACE_CDR::LongDouble::assign(), ACE_CDR::LongDouble::operator NativeImpl(), ACE_InputCDR::read_16(), swap_16_array(), and ACE_OutputCDR::write_16().

00198 {
00199   swap_8 (orig + 8, target);
00200   swap_8 (orig, target + 8);
00201 }

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

Definition at line 476 of file CDR_Base.cpp.

References swap_16().

Referenced by ACE_InputCDR::read_array(), and ACE_OutputCDR::write_array().

00477 {
00478   // ACE_ASSERT(n > 0); The caller checks that n > 0
00479 
00480   char const * const end = orig + 16*n;
00481   while (orig < end)
00482     {
00483       swap_16 (orig, target);
00484       orig += 16;
00485       target += 16;
00486     }
00487 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE void ACE_CDR::swap_2 ( char const *  orig,
char *  target 
) [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.

Referenced by ACE_InputCDR::read_2(), ACE_InputCDR::read_wchar_array_i(), ACE_OutputCDR::replace(), swap_2_array(), ACE_OutputCDR::write_2(), and ACE_OutputCDR::write_wchar_array_i().

00067 {
00068 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
00069   // Take advantage of MSVC++ compiler intrinsic byte swapping
00070   // function.
00071   *reinterpret_cast<unsigned short *> (target) =
00072     _byteswap_ushort (*reinterpret_cast<unsigned short const *> (orig));
00073 #elif defined (ACE_HAS_BSWAP16)
00074   *reinterpret_cast<uint16_t *> (target) =
00075     bswap16 (*reinterpret_cast<uint16_t const *> (orig));
00076 #elif defined (ACE_HAS_BSWAP_16)
00077   *reinterpret_cast<uint16_t *> (target) =
00078     bswap_16 (*reinterpret_cast<uint16_t const *> (orig));
00079 #elif defined(ACE_HAS_INTEL_ASSEMBLY)
00080   unsigned short a =
00081     *reinterpret_cast<const unsigned short*> (orig);
00082   asm( "rolw $8, %0" : "=r" (a) : "0" (a) );
00083   *reinterpret_cast<unsigned short*> (target) = a;
00084 #elif defined (ACE_HAS_PENTIUM) \
00085        && (defined(_MSC_VER) || defined(__BORLANDC__)) \
00086        && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00087   __asm mov ebx, orig;
00088   __asm mov ecx, target;
00089   __asm mov ax, [ebx];
00090   __asm rol ax, 8;
00091   __asm mov [ecx], ax;
00092 #else
00093   register ACE_UINT16 usrc = * reinterpret_cast<const ACE_UINT16*> (orig);
00094   register ACE_UINT16* udst = reinterpret_cast<ACE_UINT16*> (target);
00095   *udst = (usrc << 8) | (usrc >> 8);
00096 #endif /* ACE_HAS_PENTIUM */
00097 }

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

Definition at line 27 of file CDR_Base.cpp.

References ACE_ptr_align_binary(), and swap_2().

Referenced by ACE_InputCDR::read_array(), and ACE_OutputCDR::write_array().

00028 {
00029   // ACE_ASSERT(n > 0); The caller checks that n > 0
00030 
00031   // We pretend that AMD64/GNU G++ systems have a Pentium CPU to
00032   // take advantage of the inline assembly implementation.
00033 
00034   // Later, we try to read in 32 or 64 bit chunks,
00035   // so make sure we don't do that for unaligned addresses.
00036 #if ACE_SIZEOF_LONG == 8 && \
00037     !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__))
00038   char const * const o8 = ACE_ptr_align_binary (orig, 8);
00039   while (orig < o8 && n > 0)
00040     {
00041       ACE_CDR::swap_2 (orig, target);
00042       orig += 2;
00043       target += 2;
00044       --n;
00045     }
00046 #else
00047   char const * const o4 = ACE_ptr_align_binary (orig, 4);
00048   // this is an _if_, not a _while_. The mistmatch can only be by 2.
00049   if (orig != o4)
00050     {
00051       ACE_CDR::swap_2 (orig, target);
00052       orig += 2;
00053       target += 2;
00054       --n;
00055     }
00056 #endif
00057   if (n == 0)
00058     return;
00059 
00060   //
00061   // Loop unrolling. Here be dragons.
00062   //
00063 
00064   // (n & (~3)) is the greatest multiple of 4 not bigger than n.
00065   // In the while loop ahead, orig will move over the array by 8 byte
00066   // increments (4 elements of 2 bytes).
00067   // end marks our barrier for not falling outside.
00068   char const * const end = orig + 2 * (n & (~3));
00069 
00070   // See if we're aligned for writting in 64 or 32 bit chunks...
00071 #if ACE_SIZEOF_LONG == 8 && \
00072     !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__))
00073   if (target == ACE_ptr_align_binary (target, 8))
00074 #else
00075   if (target == ACE_ptr_align_binary (target, 4))
00076 #endif
00077     {
00078       while (orig < end)
00079         {
00080 #if defined (ACE_HAS_INTEL_ASSEMBLY)
00081           unsigned int a =
00082             * reinterpret_cast<const unsigned int*> (orig);
00083           unsigned int b =
00084             * reinterpret_cast<const unsigned int*> (orig + 4);
00085           asm ( "bswap %1"      : "=r" (a) : "0" (a) );
00086           asm ( "bswap %1"      : "=r" (b) : "0" (b) );
00087           asm ( "rol $16, %1"   : "=r" (a) : "0" (a) );
00088           asm ( "rol $16, %1"   : "=r" (b) : "0" (b) );
00089           * reinterpret_cast<unsigned int*> (target) = a;
00090           * reinterpret_cast<unsigned int*> (target + 4) = b;
00091 #elif defined(ACE_HAS_PENTIUM) \
00092       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
00093       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00094           __asm mov ecx, orig;
00095           __asm mov edx, target;
00096           __asm mov eax, [ecx];
00097           __asm mov ebx, 4[ecx];
00098           __asm bswap eax;
00099           __asm bswap ebx;
00100           __asm rol eax, 16;
00101           __asm rol ebx, 16;
00102           __asm mov [edx], eax;
00103           __asm mov 4[edx], ebx;
00104 #elif ACE_SIZEOF_LONG == 8
00105           // 64 bit architecture.
00106           register unsigned long a =
00107             * reinterpret_cast<const unsigned long*> (orig);
00108 
00109           register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8;
00110           register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8;
00111 
00112           a = (a1 | a2);
00113 
00114           * reinterpret_cast<unsigned long*> (target) = a;
00115 #else
00116           register ACE_UINT32 a =
00117             * reinterpret_cast<const ACE_UINT32*> (orig);
00118           register ACE_UINT32 b =
00119             * reinterpret_cast<const ACE_UINT32*> (orig + 4);
00120 
00121           register ACE_UINT32 a1 = (a & 0x00ff00ffU) << 8;
00122           register ACE_UINT32 b1 = (b & 0x00ff00ffU) << 8;
00123           register ACE_UINT32 a2 = (a & 0xff00ff00U) >> 8;
00124           register ACE_UINT32 b2 = (b & 0xff00ff00U) >> 8;
00125 
00126           a = (a1 | a2);
00127           b = (b1 | b2);
00128 
00129           * reinterpret_cast<ACE_UINT32*> (target) = a;
00130           * reinterpret_cast<ACE_UINT32*> (target + 4) = b;
00131 #endif
00132           orig += 8;
00133           target += 8;
00134         }
00135     }
00136   else
00137     {
00138       // We're out of luck. We have to write in 2 byte chunks.
00139       while (orig < end)
00140         {
00141 #if defined (ACE_HAS_INTEL_ASSEMBLY)
00142           unsigned int a =
00143             * reinterpret_cast<const unsigned int*> (orig);
00144           unsigned int b =
00145             * reinterpret_cast<const unsigned int*> (orig + 4);
00146           asm ( "bswap %1" : "=r" (a) : "0" (a) );
00147           asm ( "bswap %1" : "=r" (b) : "0" (b) );
00148           // We're little endian.
00149           * reinterpret_cast<unsigned short*> (target + 2)
00150               = (unsigned short) (a & 0xffff);
00151           * reinterpret_cast<unsigned short*> (target + 6)
00152               = (unsigned short) (b & 0xffff);
00153           asm ( "shrl $16, %1" : "=r" (a) : "0" (a) );
00154           asm ( "shrl $16, %1" : "=r" (b) : "0" (b) );
00155           * reinterpret_cast<unsigned short*> (target + 0)
00156               = (unsigned short) (a & 0xffff);
00157           * reinterpret_cast<unsigned short*> (target + 4)
00158               = (unsigned short) (b & 0xffff);
00159 #elif defined (ACE_HAS_PENTIUM) \
00160       && (defined (_MSC_VER) || defined (__BORLANDC__)) \
00161       && !defined (ACE_LACKS_INLINE_ASSEMBLY)
00162           __asm mov ecx, orig;
00163           __asm mov edx, target;
00164           __asm mov eax, [ecx];
00165           __asm mov ebx, 4[ecx];
00166           __asm bswap eax;
00167           __asm bswap ebx;
00168           // We're little endian.
00169           __asm mov 2[edx], ax;
00170           __asm mov 6[edx], bx;
00171           __asm shr eax, 16;
00172           __asm shr ebx, 16;
00173           __asm mov 0[edx], ax;
00174           __asm mov 4[edx], bx;
00175 #elif ACE_SIZEOF_LONG == 8
00176           // 64 bit architecture.
00177           register unsigned long a =
00178             * reinterpret_cast<const unsigned long*> (orig);
00179 
00180           register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8;
00181           register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8;
00182 
00183           a = (a1 | a2);
00184 
00185           ACE_UINT16 b1 = static_cast<ACE_UINT16> (a >> 48);
00186           ACE_UINT16 b2 = static_cast<ACE_UINT16> ((a >> 32) & 0xffff);
00187           ACE_UINT16 b3 = static_cast<ACE_UINT16> ((a >> 16) & 0xffff);
00188           ACE_UINT16 b4 = static_cast<ACE_UINT16> (a & 0xffff);
00189 
00190 #if defined(ACE_LITTLE_ENDIAN)
00191           * reinterpret_cast<ACE_UINT16*> (target) = b4;
00192           * reinterpret_cast<ACE_UINT16*> (target + 2) = b3;
00193           * reinterpret_cast<ACE_UINT16*> (target + 4) = b2;
00194           * reinterpret_cast<ACE_UINT16*> (target + 6) = b1;
00195 #else
00196           * reinterpret_cast<ACE_UINT16*> (target) = b1;
00197           * reinterpret_cast<ACE_UINT16*> (target + 2) = b2;
00198           * reinterpret_cast<ACE_UINT16*> (target + 4) = b3;
00199           * reinterpret_cast<ACE_UINT16*> (target + 6) = b4;
00200 #endif
00201 #else
00202           register ACE_UINT32 a =
00203             * reinterpret_cast<const ACE_UINT32*> (orig);
00204           register ACE_UINT32 b =
00205             * reinterpret_cast<const ACE_UINT32*> (orig + 4);
00206 
00207           register ACE_UINT32 a1 = (a & 0x00ff00ff) << 8;
00208           register ACE_UINT32 b1 = (b & 0x00ff00ff) << 8;
00209           register ACE_UINT32 a2 = (a & 0xff00ff00) >> 8;
00210           register ACE_UINT32 b2 = (b & 0xff00ff00) >> 8;
00211 
00212           a = (a1 | a2);
00213           b = (b1 | b2);
00214 
00215           ACE_UINT32 c1 = static_cast<ACE_UINT16> (a >> 16);
00216           ACE_UINT32 c2 = static_cast<ACE_UINT16> (a & 0xffff);
00217           ACE_UINT32 c3 = static_cast<ACE_UINT16> (b >> 16);
00218           ACE_UINT32 c4 = static_cast<ACE_UINT16> (b & 0xffff);
00219 
00220 #if defined(ACE_LITTLE_ENDIAN)
00221           * reinterpret_cast<ACE_UINT16*> (target) = c2;
00222           * reinterpret_cast<ACE_UINT16*> (target + 2) = c1;
00223           * reinterpret_cast<ACE_UINT16*> (target + 4) = c4;
00224           * reinterpret_cast<ACE_UINT16*> (target + 6) = c3;
00225 #else
00226           * reinterpret_cast<ACE_UINT16*> (target) = c1;
00227           * reinterpret_cast<ACE_UINT16*> (target + 2) = c2;
00228           * reinterpret_cast<ACE_UINT16*> (target + 4) = c3;
00229           * reinterpret_cast<ACE_UINT16*> (target + 6) = c4;
00230 #endif
00231 #endif
00232 
00233           orig += 8;
00234           target += 8;
00235         }
00236     }
00237 
00238   // (n & 3) == (n % 4).
00239   switch (n&3) {
00240   case 3:
00241     ACE_CDR::swap_2 (orig, target);
00242     orig += 2;
00243     target += 2;
00244   case 2:
00245     ACE_CDR::swap_2 (orig, target);
00246     orig += 2;
00247     target += 2;
00248   case 1:
00249     ACE_CDR::swap_2 (orig, target);
00250   }
00251 }

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

Definition at line 100 of file CDR_Base.inl.

Referenced by ACE_InputCDR::read_4(), ACE_OutputCDR::replace(), swap_4_array(), and ACE_OutputCDR::write_4().

00101 {
00102 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
00103   // Take advantage of MSVC++ compiler intrinsic byte swapping
00104   // function.
00105   *reinterpret_cast<unsigned long *> (target) =
00106     _byteswap_ulong (*reinterpret_cast<unsigned long const *> (orig));
00107 #elif defined (ACE_HAS_BSWAP32)
00108   *reinterpret_cast<uint32_t *> (target) =
00109     bswap32 (*reinterpret_cast<uint32_t const *> (orig));
00110 #elif defined (ACE_HAS_BSWAP_32)
00111   *reinterpret_cast<uint32_t *> (target) =
00112     bswap_32 (*reinterpret_cast<uint32_t const *> (orig));
00113 #elif defined(ACE_HAS_INTEL_ASSEMBLY)
00114   // We have ACE_HAS_PENTIUM, so we know the sizeof's.
00115   register unsigned int j =
00116     *reinterpret_cast<const unsigned int*> (orig);
00117   asm ("bswap %1" : "=r" (j) : "0" (j));
00118   *reinterpret_cast<unsigned int*> (target) = j;
00119 #elif defined(ACE_HAS_PENTIUM) \
00120       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
00121       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00122   __asm mov ebx, orig;
00123   __asm mov ecx, target;
00124   __asm mov eax, [ebx];
00125   __asm bswap eax;
00126   __asm mov [ecx], eax;
00127 #else
00128   register ACE_UINT32 x = * reinterpret_cast<const ACE_UINT32*> (orig);
00129   x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
00130   * reinterpret_cast<ACE_UINT32*> (target) = x;
00131 #endif /* ACE_HAS_INTRINSIC_BYTESWAP */
00132 }

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

Definition at line 254 of file CDR_Base.cpp.

References ACE_ptr_align_binary(), and swap_4().

Referenced by ACE_InputCDR::read_array(), and ACE_OutputCDR::write_array().

00255 {
00256   // ACE_ASSERT (n > 0); The caller checks that n > 0
00257 
00258 #if ACE_SIZEOF_LONG == 8
00259   // Later, we read from *orig in 64 bit chunks,
00260   // so make sure we don't generate unaligned readings.
00261   char const * const o8 = ACE_ptr_align_binary (orig, 8);
00262   // The mismatch can only be by 4.
00263   if (orig != o8)
00264     {
00265       ACE_CDR::swap_4 (orig, target);
00266       orig += 4;
00267       target += 4;
00268       --n;
00269     }
00270 #endif  /* ACE_SIZEOF_LONG == 8 */
00271 
00272   if (n == 0)
00273     return;
00274 
00275   //
00276   // Loop unrolling. Here be dragons.
00277   //
00278 
00279   // (n & (~3)) is the greatest multiple of 4 not bigger than n.
00280   // In the while loop, orig will move over the array by 16 byte
00281   // increments (4 elements of 4 bytes).
00282   // ends marks our barrier for not falling outside.
00283   char const * const end = orig + 4 * (n & (~3));
00284 
00285 #if ACE_SIZEOF_LONG == 8
00286   // 64 bits architecture.
00287   // See if we can write in 8 byte chunks.
00288   if (target == ACE_ptr_align_binary (target, 8))
00289     {
00290       while (orig < end)
00291         {
00292           register unsigned long a =
00293             * reinterpret_cast<const long*> (orig);
00294           register unsigned long b =
00295             * reinterpret_cast<const long*> (orig + 8);
00296 
00297 #if defined(ACE_HAS_INTEL_ASSEMBLY)
00298           asm ("bswapq %1" : "=r" (a) : "0" (a));
00299           asm ("bswapq %1" : "=r" (b) : "0" (b));
00300           asm ("rol $32, %1" : "=r" (a) : "0" (a));
00301           asm ("rol $32, %1" : "=r" (b) : "0" (b));
00302 #else
00303           register unsigned long a84 = (a & 0x000000ff000000ffL) << 24;
00304           register unsigned long b84 = (b & 0x000000ff000000ffL) << 24;
00305           register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8;
00306           register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8;
00307           register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8;
00308           register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8;
00309           register unsigned long a51 = (a & 0xff000000ff000000L) >> 24;
00310           register unsigned long b51 = (b & 0xff000000ff000000L) >> 24;
00311 
00312           a = (a84 | a73 | a62 | a51);
00313           b = (b84 | b73 | b62 | b51);
00314 #endif
00315 
00316           * reinterpret_cast<long*> (target) = a;
00317           * reinterpret_cast<long*> (target + 8) = b;
00318 
00319           orig += 16;
00320           target += 16;
00321         }
00322     }
00323   else
00324     {
00325       // We are out of luck, we have to write in 4 byte chunks.
00326       while (orig < end)
00327         {
00328           register unsigned long a =
00329             * reinterpret_cast<const long*> (orig);
00330           register unsigned long b =
00331             * reinterpret_cast<const long*> (orig + 8);
00332 
00333 #if defined(ACE_HAS_INTEL_ASSEMBLY)
00334           asm ("bswapq %1" : "=r" (a) : "0" (a));
00335           asm ("bswapq %1" : "=r" (b) : "0" (b));
00336           asm ("rol $32, %1" : "=r" (a) : "0" (a));
00337           asm ("rol $32, %1" : "=r" (b) : "0" (b));
00338 #else
00339           register unsigned long a84 = (a & 0x000000ff000000ffL) << 24;
00340           register unsigned long b84 = (b & 0x000000ff000000ffL) << 24;
00341           register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8;
00342           register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8;
00343           register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8;
00344           register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8;
00345           register unsigned long a51 = (a & 0xff000000ff000000L) >> 24;
00346           register unsigned long b51 = (b & 0xff000000ff000000L) >> 24;
00347 
00348           a = (a84 | a73 | a62 | a51);
00349           b = (b84 | b73 | b62 | b51);
00350 #endif
00351 
00352           ACE_UINT32 c1 = static_cast<ACE_UINT32> (a >> 32);
00353           ACE_UINT32 c2 = static_cast<ACE_UINT32> (a & 0xffffffff);
00354           ACE_UINT32 c3 = static_cast<ACE_UINT32> (b >> 32);
00355           ACE_UINT32 c4 = static_cast<ACE_UINT32> (b & 0xffffffff);
00356 
00357 #if defined (ACE_LITTLE_ENDIAN)
00358           * reinterpret_cast<ACE_UINT32*> (target + 0) = c2;
00359           * reinterpret_cast<ACE_UINT32*> (target + 4) = c1;
00360           * reinterpret_cast<ACE_UINT32*> (target + 8) = c4;
00361           * reinterpret_cast<ACE_UINT32*> (target + 12) = c3;
00362 #else
00363           * reinterpret_cast<ACE_UINT32*> (target + 0) = c1;
00364           * reinterpret_cast<ACE_UINT32*> (target + 4) = c2;
00365           * reinterpret_cast<ACE_UINT32*> (target + 8) = c3;
00366           * reinterpret_cast<ACE_UINT32*> (target + 12) = c4;
00367 #endif
00368           orig += 16;
00369           target += 16;
00370         }
00371     }
00372 
00373 #else  /* ACE_SIZEOF_LONG != 8 */
00374 
00375   while (orig < end)
00376     {
00377 #if defined (ACE_HAS_PENTIUM) && defined (__GNUG__)
00378       register unsigned int a =
00379         *reinterpret_cast<const unsigned int*> (orig);
00380       register unsigned int b =
00381         *reinterpret_cast<const unsigned int*> (orig + 4);
00382       register unsigned int c =
00383         *reinterpret_cast<const unsigned int*> (orig + 8);
00384       register unsigned int d =
00385         *reinterpret_cast<const unsigned int*> (orig + 12);
00386 
00387       asm ("bswap %1" : "=r" (a) : "0" (a));
00388       asm ("bswap %1" : "=r" (b) : "0" (b));
00389       asm ("bswap %1" : "=r" (c) : "0" (c));
00390       asm ("bswap %1" : "=r" (d) : "0" (d));
00391 
00392       *reinterpret_cast<unsigned int*> (target) = a;
00393       *reinterpret_cast<unsigned int*> (target + 4) = b;
00394       *reinterpret_cast<unsigned int*> (target + 8) = c;
00395       *reinterpret_cast<unsigned int*> (target + 12) = d;
00396 #elif defined (ACE_HAS_PENTIUM) \
00397       && (defined (_MSC_VER) || defined (__BORLANDC__)) \
00398       && !defined (ACE_LACKS_INLINE_ASSEMBLY)
00399       __asm mov eax, orig
00400       __asm mov esi, target
00401       __asm mov edx, [eax]
00402       __asm mov ecx, 4[eax]
00403       __asm mov ebx, 8[eax]
00404       __asm mov eax, 12[eax]
00405       __asm bswap edx
00406       __asm bswap ecx
00407       __asm bswap ebx
00408       __asm bswap eax
00409       __asm mov [esi], edx
00410       __asm mov 4[esi], ecx
00411       __asm mov 8[esi], ebx
00412       __asm mov 12[esi], eax
00413 #else
00414       register ACE_UINT32 a =
00415         * reinterpret_cast<const ACE_UINT32*> (orig);
00416       register ACE_UINT32 b =
00417         * reinterpret_cast<const ACE_UINT32*> (orig + 4);
00418       register ACE_UINT32 c =
00419         * reinterpret_cast<const ACE_UINT32*> (orig + 8);
00420       register ACE_UINT32 d =
00421         * reinterpret_cast<const ACE_UINT32*> (orig + 12);
00422 
00423       // Expect the optimizer reordering this A LOT.
00424       // We leave it this way for clarity.
00425       a = (a << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8) | (a >> 24);
00426       b = (b << 24) | ((b & 0xff00) << 8) | ((b & 0xff0000) >> 8) | (b >> 24);
00427       c = (c << 24) | ((c & 0xff00) << 8) | ((c & 0xff0000) >> 8) | (c >> 24);
00428       d = (d << 24) | ((d & 0xff00) << 8) | ((d & 0xff0000) >> 8) | (d >> 24);
00429 
00430       * reinterpret_cast<ACE_UINT32*> (target) = a;
00431       * reinterpret_cast<ACE_UINT32*> (target + 4) = b;
00432       * reinterpret_cast<ACE_UINT32*> (target + 8) = c;
00433       * reinterpret_cast<ACE_UINT32*> (target + 12) = d;
00434 #endif
00435 
00436       orig += 16;
00437       target += 16;
00438     }
00439 
00440 #endif /* ACE_SIZEOF_LONG == 8 */
00441 
00442   // (n & 3) == (n % 4).
00443   switch (n & 3) {
00444   case 3:
00445     ACE_CDR::swap_4 (orig, target);
00446     orig += 4;
00447     target += 4;
00448   case 2:
00449     ACE_CDR::swap_4 (orig, target);
00450     orig += 4;
00451     target += 4;
00452   case 1:
00453     ACE_CDR::swap_4 (orig, target);
00454   }
00455 }

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

Definition at line 135 of file CDR_Base.inl.

Referenced by ACE_CDR::LongDouble::assign(), ACE_Name_Request::decode(), ACE_Name_Request::encode(), ACE_CDR::LongDouble::operator NativeImpl(), ACE_InputCDR::read_8(), swap_16(), swap_8_array(), and ACE_OutputCDR::write_8().

00136 {
00137 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
00138   // Take advantage of MSVC++ compiler intrinsic byte swapping
00139   // function.
00140   *reinterpret_cast<unsigned __int64 *> (target) =
00141     _byteswap_uint64 (*reinterpret_cast<unsigned __int64 const *> (orig));
00142 #elif defined (ACE_HAS_BSWAP64)
00143   *reinterpret_cast<uint64_t *> (target) =
00144     bswap64 (*reinterpret_cast<uint64_t const *> (orig));
00145 #elif defined (ACE_HAS_BSWAP_64)
00146   *reinterpret_cast<uint64_t *> (target) =
00147     bswap_64 (*reinterpret_cast<uint64_t const *> (orig));
00148 #elif (defined (__amd64__) || defined (__x86_64__)) && defined(__GNUG__)
00149   register unsigned long x =
00150     * reinterpret_cast<const unsigned long*> (orig);
00151   asm ("bswapq %1" : "=r" (x) : "0" (x));
00152   *reinterpret_cast<unsigned long*> (target) = x;
00153 #elif defined(ACE_HAS_PENTIUM) && defined(__GNUG__)
00154   register unsigned int i =
00155     *reinterpret_cast<const unsigned int*> (orig);
00156   register unsigned int j =
00157     *reinterpret_cast<const unsigned int*> (orig + 4);
00158   asm ("bswap %1" : "=r" (i) : "0" (i));
00159   asm ("bswap %1" : "=r" (j) : "0" (j));
00160   *reinterpret_cast<unsigned int*> (target + 4) = i;
00161   *reinterpret_cast<unsigned int*> (target) = j;
00162 #elif defined(ACE_HAS_PENTIUM) \
00163       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
00164       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00165   __asm mov ecx, orig;
00166   __asm mov edx, target;
00167   __asm mov eax, [ecx];
00168   __asm mov ebx, 4[ecx];
00169   __asm bswap eax;
00170   __asm bswap ebx;
00171   __asm mov 4[edx], eax;
00172   __asm mov [edx], ebx;
00173 #elif ACE_SIZEOF_LONG == 8
00174   // 64 bit architecture.
00175   register unsigned long x =
00176     * reinterpret_cast<const unsigned long*> (orig);
00177   register unsigned long x84 = (x & 0x000000ff000000ffUL) << 24;
00178   register unsigned long x73 = (x & 0x0000ff000000ff00UL) << 8;
00179   register unsigned long x62 = (x & 0x00ff000000ff0000UL) >> 8;
00180   register unsigned long x51 = (x & 0xff000000ff000000UL) >> 24;
00181   x = (x84 | x73 | x62 | x51);
00182   x = (x << 32) | (x >> 32);
00183   *reinterpret_cast<unsigned long*> (target) = x;
00184 #else
00185   register ACE_UINT32 x =
00186     * reinterpret_cast<const ACE_UINT32*> (orig);
00187   register ACE_UINT32 y =
00188     * reinterpret_cast<const ACE_UINT32*> (orig + 4);
00189   x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
00190   y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24);
00191   * reinterpret_cast<ACE_UINT32*> (target) = y;
00192   * reinterpret_cast<ACE_UINT32*> (target + 4) = x;
00193 #endif /* ACE_HAS_INTRINSIC_BYTESWAP */
00194 }

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

Definition at line 462 of file CDR_Base.cpp.

References swap_8().

Referenced by ACE_InputCDR::read_array(), and ACE_OutputCDR::write_array().

00463 {
00464   // ACE_ASSERT(n > 0); The caller checks that n > 0
00465 
00466   char const * const end = orig + 8*n;
00467   while (orig < end)
00468     {
00469       swap_8 (orig, target);
00470       orig += 8;
00471       target += 8;
00472     }
00473 }

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.

References ACE_Message_Block::cont().

Referenced by consolidate(), and ACE_OutputCDR::total_length().

00542 {
00543   size_t l = 0;
00544   // Compute the total size.
00545   for (const ACE_Message_Block *i = begin;
00546        i != end;
00547        i = i->cont ())
00548     l += i->length ();
00549   return l;
00550 }


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:34:59 2010 for ACE by  doxygen 1.4.7