Keep constants and some routines common to both Output and Input CDR streams. More...
#include <CDR_Base.h>
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 | |
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) |
Keep constants and some routines common to both Output and Input CDR streams.
Definition at line 62 of file CDR_Base.h.
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.
typedef ACE_UINT64 ACE_CDR::ULongLong |
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.
anonymous enum |
OCTET_SIZE | |
SHORT_SIZE | |
LONG_SIZE | |
LONGLONG_SIZE | |
LONGDOUBLE_SIZE | |
OCTET_ALIGN | |
SHORT_ALIGN | |
LONG_ALIGN | |
LONGLONG_ALIGN | |
LONGDOUBLE_ALIGN |
|
MAX_ALIGNMENT |
Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long double", size as above). |
DEFAULT_BUFSIZE |
The default buffer size.
|
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 };
enum ACE_CDR::Byte_Order |
Defines values for the byte_order argument to ACE_OutputCDR and ACE_InputCDR.
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 };
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.
-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.
-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.
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; }