CDR_Base.cpp

Go to the documentation of this file.
00001 #include "ace/CDR_Base.h"
00002 
00003 #if !defined (__ACE_INLINE__)
00004 # include "ace/CDR_Base.inl"
00005 #endif /* ! __ACE_INLINE__ */
00006 
00007 #include "ace/Message_Block.h"
00008 #include "ace/OS_Memory.h"
00009 #include "ace/OS_NS_string.h"
00010 
00011 ACE_RCSID (ace,
00012            CDR_Base,
00013            "$Id: CDR_Base.cpp 80826 2008-03-04 14:51:23Z wotte $")
00014 
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 #if defined (NONNATIVE_LONGDOUBLE)
00018 static const ACE_INT16 max_eleven_bit = 0x3ff;
00019 static const ACE_INT16 max_fifteen_bit = 0x3fff;
00020 #endif /* NONNATIVE_LONGDOUBLE */
00021 
00022 //
00023 // See comments in CDR_Base.inl about optimization cases for swap_XX_array.
00024 //
00025 
00026 void
00027 ACE_CDR::swap_2_array (char const * orig, char* target, size_t n)
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 }
00252 
00253 void
00254 ACE_CDR::swap_4_array (char const * orig, char* target, size_t n)
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 }
00456 
00457 //
00458 // We don't benefit from unrolling in swap_8_array and swap_16_array
00459 // (swap_8 and swap_16 are big enough).
00460 //
00461 void
00462 ACE_CDR::swap_8_array (char const * orig, char* target, size_t n)
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 }
00474 
00475 void
00476 ACE_CDR::swap_16_array (char const * orig, char* target, size_t n)
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 }
00488 
00489 void
00490 ACE_CDR::mb_align (ACE_Message_Block *mb)
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 }
00501 
00502 int
00503 ACE_CDR::grow (ACE_Message_Block *mb, size_t minsize)
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 }
00538 
00539 size_t
00540 ACE_CDR::total_length (const ACE_Message_Block* begin,
00541                        const ACE_Message_Block* end)
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 }
00551 
00552 void
00553 ACE_CDR::consolidate (ACE_Message_Block *dst,
00554                       const ACE_Message_Block *src)
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 }
00590 
00591 #if defined (NONNATIVE_LONGLONG)
00592 bool
00593 ACE_CDR::LongLong::operator== (const ACE_CDR::LongLong &rhs) const
00594 {
00595   return this->h == rhs.h && this->l == rhs.l;
00596 }
00597 
00598 bool
00599 ACE_CDR::LongLong::operator!= (const ACE_CDR::LongLong &rhs) const
00600 {
00601   return this->l != rhs.l || this->h != rhs.h;
00602 }
00603 
00604 #endif /* NONNATIVE_LONGLONG */
00605 
00606 #if defined (NONNATIVE_LONGDOUBLE)
00607 ACE_CDR::LongDouble&
00608 ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble::NativeImpl& rhs)
00609 {
00610   ACE_OS::memset (this->ld, 0, sizeof (this->ld));
00611 
00612   if (sizeof (rhs) == 8)
00613     {
00614 #if defined (ACE_LITTLE_ENDIAN)
00615       static const size_t byte_zero = 1;
00616       static const size_t byte_one = 0;
00617       char rhs_ptr[16];
00618       ACE_CDR::swap_8 (reinterpret_cast<const char*> (&rhs), rhs_ptr);
00619 #else
00620       static const size_t byte_zero = 0;
00621       static const size_t byte_one = 1;
00622       const char* rhs_ptr = reinterpret_cast<const char*> (&rhs);
00623 #endif
00624       ACE_INT16 sign  = static_cast<ACE_INT16> (
00625                           static_cast<signed char> (rhs_ptr[0])) & 0x8000;
00626       ACE_INT16 exponent = ((rhs_ptr[0] & 0x7f) << 4) |
00627                            ((rhs_ptr[1] >> 4) & 0xf);
00628       const char* exp_ptr = reinterpret_cast<const char*> (&exponent);
00629 
00630       // Infinity and NaN have an exponent of 0x7ff in 64-bit IEEE
00631       if (exponent == 0x7ff)
00632         {
00633           exponent = 0x7fff;
00634         }
00635       else
00636         {
00637           exponent = (exponent - max_eleven_bit) + max_fifteen_bit;
00638         }
00639       exponent |= sign;
00640 
00641       // Store the sign bit and exponent
00642       this->ld[0] = exp_ptr[byte_zero];
00643       this->ld[1] = exp_ptr[byte_one];
00644 
00645       // Store the mantissa.  In an 8 byte double, it is split by
00646       // 4 bits (because of the 12 bits for sign and exponent), so
00647       // we have to shift and or the rhs to get the right bytes.
00648       size_t li = 2;
00649       bool direction = true;
00650       for (size_t ri = 1; ri < sizeof (rhs);)
00651         {
00652           if (direction)
00653             {
00654               this->ld[li] |= ((rhs_ptr[ri] << 4) & 0xf0);
00655               direction = false;
00656               ++ri;
00657             }
00658           else
00659             {
00660               this->ld[li] |= ((rhs_ptr[ri] >> 4) & 0xf);
00661               direction = true;
00662               ++li;
00663             }
00664         }
00665 #if defined (ACE_LITTLE_ENDIAN)
00666       ACE_OS::memcpy (rhs_ptr, this->ld, sizeof (this->ld));
00667       ACE_CDR::swap_16 (rhs_ptr, this->ld);
00668 #endif
00669     }
00670   else
00671     {
00672       ACE_OS::memcpy(this->ld,
00673                      reinterpret_cast<const char*> (&rhs), sizeof (rhs));
00674     }
00675   return *this;
00676 }
00677 
00678 ACE_CDR::LongDouble&
00679 ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble& rhs)
00680 {
00681   if (this != &rhs)
00682     *this = rhs;
00683   return *this;
00684 }
00685 
00686 bool
00687 ACE_CDR::LongDouble::operator== (const ACE_CDR::LongDouble &rhs) const
00688 {
00689   return ACE_OS::memcmp (this->ld, rhs.ld, 16) == 0;
00690 }
00691 
00692 bool
00693 ACE_CDR::LongDouble::operator!= (const ACE_CDR::LongDouble &rhs) const
00694 {
00695   return ACE_OS::memcmp (this->ld, rhs.ld, 16) != 0;
00696 }
00697 
00698 ACE_CDR::LongDouble::operator ACE_CDR::LongDouble::NativeImpl () const
00699 {
00700   ACE_CDR::LongDouble::NativeImpl ret = 0.0;
00701   char* lhs_ptr = reinterpret_cast<char*> (&ret);
00702 
00703   if (sizeof (ret) == 8)
00704     {
00705 #if defined (ACE_LITTLE_ENDIAN)
00706       static const size_t byte_zero = 1;
00707       static const size_t byte_one = 0;
00708       char copy[16];
00709       ACE_CDR::swap_16 (this->ld, copy);
00710 #else
00711       static const size_t byte_zero = 0;
00712       static const size_t byte_one = 1;
00713       const char* copy = this->ld;
00714 #endif
00715       ACE_INT16 exponent = 0;
00716       char* exp_ptr = reinterpret_cast<char*> (&exponent);
00717       exp_ptr[byte_zero] = copy[0];
00718       exp_ptr[byte_one] = copy[1];
00719 
00720       ACE_INT16 sign = (exponent & 0x8000);
00721       exponent &= 0x7fff;
00722 
00723       // Infinity and NaN have an exponent of 0x7fff in 128-bit IEEE
00724       if (exponent == 0x7fff)
00725         {
00726           exponent = 0x7ff;
00727         }
00728       else
00729         {
00730           exponent = (exponent - max_fifteen_bit) + max_eleven_bit;
00731         }
00732       exponent = (exponent << 4) | sign;
00733 
00734       // Store the sign and exponent
00735       lhs_ptr[0] = exp_ptr[byte_zero];
00736       lhs_ptr[1] = exp_ptr[byte_one];
00737 
00738       // Store the mantissa.  In an 8 byte double, it is split by
00739       // 4 bits (because of the 12 bits for sign and exponent), so
00740       // we have to shift and or the rhs to get the right bytes.
00741       size_t li = 1;
00742       bool direction = true;
00743       for (size_t ri = 2; li < sizeof (ret);) {
00744         if (direction)
00745           {
00746             lhs_ptr[li] |= ((copy[ri] >> 4) & 0xf);
00747             direction = false;
00748             ++li;
00749           }
00750         else
00751           {
00752             lhs_ptr[li] |= ((copy[ri] & 0xf) << 4);
00753             direction = true;
00754             ++ri;
00755           }
00756       }
00757 
00758 #if defined (ACE_LITTLE_ENDIAN)
00759       ACE_CDR::swap_8 (lhs_ptr, lhs_ptr);
00760 #endif
00761     }
00762   else
00763     {
00764       ACE_OS::memcpy(lhs_ptr, this->ld, sizeof (ret));
00765     }
00766 
00767   // This bit of code is unnecessary.  However, this code is
00768   // necessary to work around a bug in the gcc 4.1.1 optimizer.
00769   ACE_CDR::LongDouble tmp;
00770   tmp.assign (ret);
00771 
00772   return ret;
00773 }
00774 #endif /* NONNATIVE_LONGDOUBLE */
00775 
00776 #if defined(_UNICOS) && !defined(_CRAYMPP)
00777 // placeholders to get things compiling
00778 ACE_CDR::Float::Float (void)
00779 {
00780 }
00781 
00782 ACE_CDR::Float::Float (const float & /* init */)
00783 {
00784 }
00785 
00786 ACE_CDR::Float &
00787 ACE_CDR::Float::operator= (const float & /* rhs */)
00788 {
00789   return *this;
00790 }
00791 
00792 bool
00793 ACE_CDR::Float::operator!= (const ACE_CDR::Float & /* rhs */) const
00794 {
00795   return false;
00796 }
00797 #endif /* _UNICOS */
00798 
00799 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7