00001 #include "ace/CDR_Base.h"
00002
00003 #if !defined (__ACE_INLINE__)
00004 # include "ace/CDR_Base.inl"
00005 #endif
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 "CDR_Base.cpp,v 4.23 2006/02/28 00:23:12 shuston Exp")
00014
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016
00017
00018
00019
00020
00021 void
00022 ACE_CDR::swap_2_array (const char* orig, char* target, size_t n)
00023 {
00024
00025
00026
00027
00028
00029
00030
00031 #if ACE_SIZEOF_LONG == 8 && \
00032 !(defined(__amd64__) && defined(__GNUG__))
00033 const char* const o8 = ACE_ptr_align_binary (orig, 8);
00034 while (orig < o8 && n > 0)
00035 {
00036 ACE_CDR::swap_2 (orig, target);
00037 orig += 2;
00038 target += 2;
00039 --n;
00040 }
00041 #else
00042 const char* const o4 = ACE_ptr_align_binary (orig, 4);
00043
00044 if (orig != o4)
00045 {
00046 ACE_CDR::swap_2 (orig, target);
00047 orig += 2;
00048 target += 2;
00049 --n;
00050 }
00051 #endif
00052 if (n == 0)
00053 return;
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 const char* const end = orig + 2 * (n & (~3));
00064
00065
00066 #if ACE_SIZEOF_LONG == 8 && \
00067 !(defined(__amd64__) && defined(__GNUG__))
00068 if (target == ACE_ptr_align_binary (target, 8))
00069 #else
00070 if (target == ACE_ptr_align_binary (target, 4))
00071 #endif
00072 {
00073 while (orig < end)
00074 {
00075 #if (defined (ACE_HAS_PENTIUM) || defined(__amd64__)) && defined (__GNUG__)
00076 unsigned int a =
00077 * reinterpret_cast<const unsigned int*> (orig);
00078 unsigned int b =
00079 * reinterpret_cast<const unsigned int*> (orig + 4);
00080 asm ( "bswap %1" : "=r" (a) : "0" (a) );
00081 asm ( "bswap %1" : "=r" (b) : "0" (b) );
00082 asm ( "rol $16, %1" : "=r" (a) : "0" (a) );
00083 asm ( "rol $16, %1" : "=r" (b) : "0" (b) );
00084 * reinterpret_cast<unsigned int*> (target) = a;
00085 * reinterpret_cast<unsigned int*> (target + 4) = b;
00086 #elif defined(ACE_HAS_PENTIUM) \
00087 && (defined(_MSC_VER) || defined(__BORLANDC__)) \
00088 && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00089 __asm mov ecx, orig;
00090 __asm mov edx, target;
00091 __asm mov eax, [ecx];
00092 __asm mov ebx, 4[ecx];
00093 __asm bswap eax;
00094 __asm bswap ebx;
00095 __asm rol eax, 16;
00096 __asm rol ebx, 16;
00097 __asm mov [edx], eax;
00098 __asm mov 4[edx], ebx;
00099 #elif ACE_SIZEOF_LONG == 8
00100
00101 register unsigned long a =
00102 * reinterpret_cast<const unsigned long*> (orig);
00103
00104 register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8;
00105 register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8;
00106
00107 a = (a1 | a2);
00108
00109 * reinterpret_cast<unsigned long*> (target) = a;
00110 #else
00111 register ACE_UINT32 a =
00112 * reinterpret_cast<const ACE_UINT32*> (orig);
00113 register ACE_UINT32 b =
00114 * reinterpret_cast<const ACE_UINT32*> (orig + 4);
00115
00116 register ACE_UINT32 a1 = (a & 0x00ff00ffU) << 8;
00117 register ACE_UINT32 b1 = (b & 0x00ff00ffU) << 8;
00118 register ACE_UINT32 a2 = (a & 0xff00ff00U) >> 8;
00119 register ACE_UINT32 b2 = (b & 0xff00ff00U) >> 8;
00120
00121 a = (a1 | a2);
00122 b = (b1 | b2);
00123
00124 * reinterpret_cast<ACE_UINT32*> (target) = a;
00125 * reinterpret_cast<ACE_UINT32*> (target + 4) = b;
00126 #endif
00127 orig += 8;
00128 target += 8;
00129 }
00130 }
00131 else
00132 {
00133
00134 while (orig < end)
00135 {
00136 #if (defined (ACE_HAS_PENTIUM) || defined(__amd64__)) && defined (__GNUG__)
00137 unsigned int a =
00138 * reinterpret_cast<const unsigned int*> (orig);
00139 unsigned int b =
00140 * reinterpret_cast<const unsigned int*> (orig + 4);
00141 asm ( "bswap %1" : "=r" (a) : "0" (a) );
00142 asm ( "bswap %1" : "=r" (b) : "0" (b) );
00143
00144 * reinterpret_cast<unsigned short*> (target + 2)
00145 = (unsigned short) (a & 0xffff);
00146 * reinterpret_cast<unsigned short*> (target + 6)
00147 = (unsigned short) (b & 0xffff);
00148 asm ( "shrl $16, %1" : "=r" (a) : "0" (a) );
00149 asm ( "shrl $16, %1" : "=r" (b) : "0" (b) );
00150 * reinterpret_cast<unsigned short*> (target + 0)
00151 = (unsigned short) (a & 0xffff);
00152 * reinterpret_cast<unsigned short*> (target + 4)
00153 = (unsigned short) (b & 0xffff);
00154 #elif defined (ACE_HAS_PENTIUM) \
00155 && (defined (_MSC_VER) || defined (__BORLANDC__)) \
00156 && !defined (ACE_LACKS_INLINE_ASSEMBLY)
00157 __asm mov ecx, orig;
00158 __asm mov edx, target;
00159 __asm mov eax, [ecx];
00160 __asm mov ebx, 4[ecx];
00161 __asm bswap eax;
00162 __asm bswap ebx;
00163
00164 __asm mov 2[edx], ax;
00165 __asm mov 6[edx], bx;
00166 __asm shr eax, 16;
00167 __asm shr ebx, 16;
00168 __asm mov 0[edx], ax;
00169 __asm mov 4[edx], bx;
00170 #elif ACE_SIZEOF_LONG == 8
00171
00172 register unsigned long a =
00173 * reinterpret_cast<const unsigned long*> (orig);
00174
00175 register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8;
00176 register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8;
00177
00178 a = (a1 | a2);
00179
00180 ACE_UINT16 b1 = static_cast<ACE_UINT16> (a >> 48);
00181 ACE_UINT16 b2 = static_cast<ACE_UINT16> ((a >> 32) & 0xffff);
00182 ACE_UINT16 b3 = static_cast<ACE_UINT16> ((a >> 16) & 0xffff);
00183 ACE_UINT16 b4 = static_cast<ACE_UINT16> (a & 0xffff);
00184
00185 #if defined(ACE_LITTLE_ENDIAN)
00186 * reinterpret_cast<ACE_UINT16*> (target) = b4;
00187 * reinterpret_cast<ACE_UINT16*> (target + 2) = b3;
00188 * reinterpret_cast<ACE_UINT16*> (target + 4) = b2;
00189 * reinterpret_cast<ACE_UINT16*> (target + 6) = b1;
00190 #else
00191 * reinterpret_cast<ACE_UINT16*> (target) = b1;
00192 * reinterpret_cast<ACE_UINT16*> (target + 2) = b2;
00193 * reinterpret_cast<ACE_UINT16*> (target + 4) = b3;
00194 * reinterpret_cast<ACE_UINT16*> (target + 6) = b4;
00195 #endif
00196 #else
00197 register ACE_UINT32 a =
00198 * reinterpret_cast<const ACE_UINT32*> (orig);
00199 register ACE_UINT32 b =
00200 * reinterpret_cast<const ACE_UINT32*> (orig + 4);
00201
00202 register ACE_UINT32 a1 = (a & 0x00ff00ff) << 8;
00203 register ACE_UINT32 b1 = (b & 0x00ff00ff) << 8;
00204 register ACE_UINT32 a2 = (a & 0xff00ff00) >> 8;
00205 register ACE_UINT32 b2 = (b & 0xff00ff00) >> 8;
00206
00207 a = (a1 | a2);
00208 b = (b1 | b2);
00209
00210 ACE_UINT32 c1 = static_cast<ACE_UINT16> (a >> 16);
00211 ACE_UINT32 c2 = static_cast<ACE_UINT16> (a & 0xffff);
00212 ACE_UINT32 c3 = static_cast<ACE_UINT16> (b >> 16);
00213 ACE_UINT32 c4 = static_cast<ACE_UINT16> (b & 0xffff);
00214
00215 #if defined(ACE_LITTLE_ENDIAN)
00216 * reinterpret_cast<ACE_UINT16*> (target) = c2;
00217 * reinterpret_cast<ACE_UINT16*> (target + 2) = c1;
00218 * reinterpret_cast<ACE_UINT16*> (target + 4) = c4;
00219 * reinterpret_cast<ACE_UINT16*> (target + 6) = c3;
00220 #else
00221 * reinterpret_cast<ACE_UINT16*> (target) = c1;
00222 * reinterpret_cast<ACE_UINT16*> (target + 2) = c2;
00223 * reinterpret_cast<ACE_UINT16*> (target + 4) = c3;
00224 * reinterpret_cast<ACE_UINT16*> (target + 6) = c4;
00225 #endif
00226 #endif
00227
00228 orig += 8;
00229 target += 8;
00230 }
00231 }
00232
00233
00234 switch (n&3) {
00235 case 3:
00236 ACE_CDR::swap_2 (orig, target);
00237 orig += 2;
00238 target += 2;
00239 case 2:
00240 ACE_CDR::swap_2 (orig, target);
00241 orig += 2;
00242 target += 2;
00243 case 1:
00244 ACE_CDR::swap_2 (orig, target);
00245 }
00246 }
00247
00248 void
00249 ACE_CDR::swap_4_array (const char* orig, char* target, size_t n)
00250 {
00251
00252
00253 #if ACE_SIZEOF_LONG == 8
00254
00255
00256 const char* const o8 = ACE_ptr_align_binary (orig, 8);
00257
00258 if (orig != o8)
00259 {
00260 ACE_CDR::swap_4 (orig, target);
00261 orig += 4;
00262 target += 4;
00263 --n;
00264 }
00265 #endif
00266
00267 if (n == 0)
00268 return;
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 const char* const end = orig + 4 * (n & (~3));
00279
00280 #if ACE_SIZEOF_LONG == 8
00281
00282
00283 if (target == ACE_ptr_align_binary (target, 8))
00284 {
00285 while (orig < end)
00286 {
00287 register unsigned long a =
00288 * reinterpret_cast<const long*> (orig);
00289 register unsigned long b =
00290 * reinterpret_cast<const long*> (orig + 8);
00291
00292 #if defined(__amd64__) && defined(__GNUC__)
00293 asm ("bswapq %1" : "=r" (a) : "0" (a));
00294 asm ("bswapq %1" : "=r" (b) : "0" (b));
00295 asm ("rol $32, %1" : "=r" (a) : "0" (a));
00296 asm ("rol $32, %1" : "=r" (b) : "0" (b));
00297 #else
00298 register unsigned long a84 = (a & 0x000000ff000000ffL) << 24;
00299 register unsigned long b84 = (b & 0x000000ff000000ffL) << 24;
00300 register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8;
00301 register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8;
00302 register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8;
00303 register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8;
00304 register unsigned long a51 = (a & 0xff000000ff000000L) >> 24;
00305 register unsigned long b51 = (b & 0xff000000ff000000L) >> 24;
00306
00307 a = (a84 | a73 | a62 | a51);
00308 b = (b84 | b73 | b62 | b51);
00309 #endif
00310
00311 * reinterpret_cast<long*> (target) = a;
00312 * reinterpret_cast<long*> (target + 8) = b;
00313
00314 orig += 16;
00315 target += 16;
00316 }
00317 }
00318 else
00319 {
00320
00321 while (orig < end)
00322 {
00323 register unsigned long a =
00324 * reinterpret_cast<const long*> (orig);
00325 register unsigned long b =
00326 * reinterpret_cast<const long*> (orig + 8);
00327
00328 #if defined(__amd64__) && defined(__GNUC__)
00329 asm ("bswapq %1" : "=r" (a) : "0" (a));
00330 asm ("bswapq %1" : "=r" (b) : "0" (b));
00331 asm ("rol $32, %1" : "=r" (a) : "0" (a));
00332 asm ("rol $32, %1" : "=r" (b) : "0" (b));
00333 #else
00334 register unsigned long a84 = (a & 0x000000ff000000ffL) << 24;
00335 register unsigned long b84 = (b & 0x000000ff000000ffL) << 24;
00336 register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8;
00337 register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8;
00338 register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8;
00339 register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8;
00340 register unsigned long a51 = (a & 0xff000000ff000000L) >> 24;
00341 register unsigned long b51 = (b & 0xff000000ff000000L) >> 24;
00342
00343 a = (a84 | a73 | a62 | a51);
00344 b = (b84 | b73 | b62 | b51);
00345 #endif
00346
00347 ACE_UINT32 c1 = static_cast<ACE_UINT32> (a >> 32);
00348 ACE_UINT32 c2 = static_cast<ACE_UINT32> (a & 0xffffffff);
00349 ACE_UINT32 c3 = static_cast<ACE_UINT32> (b >> 32);
00350 ACE_UINT32 c4 = static_cast<ACE_UINT32> (b & 0xffffffff);
00351
00352 #if defined (ACE_LITTLE_ENDIAN)
00353 * reinterpret_cast<ACE_UINT32*> (target + 0) = c2;
00354 * reinterpret_cast<ACE_UINT32*> (target + 4) = c1;
00355 * reinterpret_cast<ACE_UINT32*> (target + 8) = c4;
00356 * reinterpret_cast<ACE_UINT32*> (target + 12) = c3;
00357 #else
00358 * reinterpret_cast<ACE_UINT32*> (target + 0) = c1;
00359 * reinterpret_cast<ACE_UINT32*> (target + 4) = c2;
00360 * reinterpret_cast<ACE_UINT32*> (target + 8) = c3;
00361 * reinterpret_cast<ACE_UINT32*> (target + 12) = c4;
00362 #endif
00363 orig += 16;
00364 target += 16;
00365 }
00366 }
00367
00368 #else
00369
00370 while (orig < end)
00371 {
00372 #if defined (ACE_HAS_PENTIUM) && defined (__GNUG__)
00373 register unsigned int a =
00374 *reinterpret_cast<const unsigned int*> (orig);
00375 register unsigned int b =
00376 *reinterpret_cast<const unsigned int*> (orig + 4);
00377 register unsigned int c =
00378 *reinterpret_cast<const unsigned int*> (orig + 8);
00379 register unsigned int d =
00380 *reinterpret_cast<const unsigned int*> (orig + 12);
00381
00382 asm ("bswap %1" : "=r" (a) : "0" (a));
00383 asm ("bswap %1" : "=r" (b) : "0" (b));
00384 asm ("bswap %1" : "=r" (c) : "0" (c));
00385 asm ("bswap %1" : "=r" (d) : "0" (d));
00386
00387 *reinterpret_cast<unsigned int*> (target) = a;
00388 *reinterpret_cast<unsigned int*> (target + 4) = b;
00389 *reinterpret_cast<unsigned int*> (target + 8) = c;
00390 *reinterpret_cast<unsigned int*> (target + 12) = d;
00391 #elif defined (ACE_HAS_PENTIUM) \
00392 && (defined (_MSC_VER) || defined (__BORLANDC__)) \
00393 && !defined (ACE_LACKS_INLINE_ASSEMBLY)
00394 __asm mov eax, orig
00395 __asm mov esi, target
00396 __asm mov edx, [eax]
00397 __asm mov ecx, 4[eax]
00398 __asm mov ebx, 8[eax]
00399 __asm mov eax, 12[eax]
00400 __asm bswap edx
00401 __asm bswap ecx
00402 __asm bswap ebx
00403 __asm bswap eax
00404 __asm mov [esi], edx
00405 __asm mov 4[esi], ecx
00406 __asm mov 8[esi], ebx
00407 __asm mov 12[esi], eax
00408 #else
00409 register ACE_UINT32 a =
00410 * reinterpret_cast<const ACE_UINT32*> (orig);
00411 register ACE_UINT32 b =
00412 * reinterpret_cast<const ACE_UINT32*> (orig + 4);
00413 register ACE_UINT32 c =
00414 * reinterpret_cast<const ACE_UINT32*> (orig + 8);
00415 register ACE_UINT32 d =
00416 * reinterpret_cast<const ACE_UINT32*> (orig + 12);
00417
00418
00419
00420 a = (a << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8) | (a >> 24);
00421 b = (b << 24) | ((b & 0xff00) << 8) | ((b & 0xff0000) >> 8) | (b >> 24);
00422 c = (c << 24) | ((c & 0xff00) << 8) | ((c & 0xff0000) >> 8) | (c >> 24);
00423 d = (d << 24) | ((d & 0xff00) << 8) | ((d & 0xff0000) >> 8) | (d >> 24);
00424
00425 * reinterpret_cast<ACE_UINT32*> (target) = a;
00426 * reinterpret_cast<ACE_UINT32*> (target + 4) = b;
00427 * reinterpret_cast<ACE_UINT32*> (target + 8) = c;
00428 * reinterpret_cast<ACE_UINT32*> (target + 12) = d;
00429 #endif
00430
00431 orig += 16;
00432 target += 16;
00433 }
00434
00435 #endif
00436
00437
00438 switch (n & 3) {
00439 case 3:
00440 ACE_CDR::swap_4 (orig, target);
00441 orig += 4;
00442 target += 4;
00443 case 2:
00444 ACE_CDR::swap_4 (orig, target);
00445 orig += 4;
00446 target += 4;
00447 case 1:
00448 ACE_CDR::swap_4 (orig, target);
00449 }
00450 }
00451
00452
00453
00454
00455
00456 void
00457 ACE_CDR::swap_8_array (const char* orig, char* target, size_t n)
00458 {
00459
00460
00461 const char* const end = orig + 8*n;
00462 while (orig < end)
00463 {
00464 swap_8 (orig, target);
00465 orig += 8;
00466 target += 8;
00467 }
00468 }
00469
00470 void
00471 ACE_CDR::swap_16_array (const char* orig, char* target, size_t n)
00472 {
00473
00474
00475 const char* const end = orig + 16*n;
00476 while (orig < end)
00477 {
00478 swap_16 (orig, target);
00479 orig += 16;
00480 target += 16;
00481 }
00482 }
00483
00484 void
00485 ACE_CDR::mb_align (ACE_Message_Block *mb)
00486 {
00487 #if !defined (ACE_CDR_IGNORE_ALIGNMENT)
00488 char *start = ACE_ptr_align_binary (mb->base (),
00489 ACE_CDR::MAX_ALIGNMENT);
00490 #else
00491 char *start = mb->base ();
00492 #endif
00493 mb->rd_ptr (start);
00494 mb->wr_ptr (start);
00495 }
00496
00497 int
00498 ACE_CDR::grow (ACE_Message_Block *mb, size_t minsize)
00499 {
00500 size_t newsize =
00501 ACE_CDR::first_size (minsize + ACE_CDR::MAX_ALIGNMENT);
00502
00503 if (newsize <= mb->size ())
00504 return 0;
00505
00506 ACE_Data_Block *db =
00507 mb->data_block ()->clone_nocopy ();
00508
00509 if (db->size (newsize) == -1)
00510 return -1;
00511
00512 ACE_Message_Block tmp (db);
00513 ACE_CDR::mb_align (&tmp);
00514
00515 tmp.copy (mb->rd_ptr (), mb->length());
00516 mb->data_block (tmp.data_block ()->duplicate ());
00517 mb->rd_ptr (tmp.rd_ptr ());
00518 mb->wr_ptr (tmp.wr_ptr ());
00519
00520
00521 mb->clr_self_flags (ACE_Message_Block::DONT_DELETE);
00522
00523 return 0;
00524 }
00525
00526 size_t
00527 ACE_CDR::total_length (const ACE_Message_Block* begin,
00528 const ACE_Message_Block* end)
00529 {
00530 size_t l = 0;
00531
00532 for (const ACE_Message_Block *i = begin;
00533 i != end;
00534 i = i->cont ())
00535 l += i->length ();
00536 return l;
00537 }
00538
00539 void
00540 ACE_CDR::consolidate (ACE_Message_Block *dst,
00541 const ACE_Message_Block *src)
00542 {
00543 if (src == 0)
00544 return;
00545
00546 size_t newsize =
00547 ACE_CDR::first_size (ACE_CDR::total_length (src, 0)
00548 + ACE_CDR::MAX_ALIGNMENT);
00549 dst->size (newsize);
00550
00551 #if !defined (ACE_CDR_IGNORE_ALIGNMENT)
00552
00553
00554 ptrdiff_t srcalign =
00555 ptrdiff_t(src->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT;
00556 ptrdiff_t dstalign =
00557 ptrdiff_t(dst->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT;
00558 ptrdiff_t offset = srcalign - dstalign;
00559 if (offset < 0)
00560 offset += ACE_CDR::MAX_ALIGNMENT;
00561 dst->rd_ptr (static_cast<size_t> (offset));
00562 dst->wr_ptr (dst->rd_ptr ());
00563 #endif
00564
00565 for (const ACE_Message_Block* i = src;
00566 i != 0;
00567 i = i->cont ())
00568 {
00569 dst->copy (i->rd_ptr (), i->length ());
00570 }
00571 }
00572
00573 #if defined (NONNATIVE_LONGLONG)
00574 bool
00575 ACE_CDR::LongLong::operator== (const ACE_CDR::LongLong &rhs) const
00576 {
00577 return this->h == rhs.h && this->l == rhs.l;
00578 }
00579
00580 bool
00581 ACE_CDR::LongLong::operator!= (const ACE_CDR::LongLong &rhs) const
00582 {
00583 return this->l != rhs.l || this->h != rhs.h;
00584 }
00585
00586 #endif
00587
00588 #if defined (NONNATIVE_LONGDOUBLE)
00589 bool
00590 ACE_CDR::LongDouble::operator== (const ACE_CDR::LongDouble &rhs) const
00591 {
00592 return ACE_OS::memcmp (this->ld, rhs.ld, 16) == 0;
00593 }
00594
00595 bool
00596 ACE_CDR::LongDouble::operator!= (const ACE_CDR::LongDouble &rhs) const
00597 {
00598 return ACE_OS::memcmp (this->ld, rhs.ld, 16) != 0;
00599 }
00600
00601 #endif
00602
00603 #if defined(_UNICOS) && !defined(_CRAYMPP)
00604
00605 ACE_CDR::Float::Float (void)
00606 {
00607 }
00608
00609 ACE_CDR::Float::Float (const float & )
00610 {
00611 }
00612
00613 ACE_CDR::Float &
00614 ACE_CDR::Float::operator= (const float & )
00615 {
00616 return *this;
00617 }
00618
00619 bool
00620 ACE_CDR::Float::operator!= (const ACE_CDR::Float & ) const
00621 {
00622 return false;
00623 }
00624 #endif
00625
00626 ACE_END_VERSIONED_NAMESPACE_DECL