diff options
Diffstat (limited to 'deps/acelite/ace/CDR_Base.cpp')
-rw-r--r-- | deps/acelite/ace/CDR_Base.cpp | 1624 |
1 files changed, 0 insertions, 1624 deletions
diff --git a/deps/acelite/ace/CDR_Base.cpp b/deps/acelite/ace/CDR_Base.cpp deleted file mode 100644 index b87380ee50..0000000000 --- a/deps/acelite/ace/CDR_Base.cpp +++ /dev/null @@ -1,1624 +0,0 @@ -#include "ace/CDR_Base.h" - -#if !defined (__ACE_INLINE__) -# include "ace/CDR_Base.inl" -#endif /* ! __ACE_INLINE__ */ - -#include "ace/Message_Block.h" -#include "ace/OS_Memory.h" -#include "ace/OS_NS_string.h" - -#ifdef ACE_LACKS_IOSTREAM_TOTALLY -#include "ace/OS_NS_stdio.h" -#else -#include "ace/streams.h" -#endif - -#include <cmath> -#include <cstring> -#include <limits> -#include <algorithm> - -ACE_BEGIN_VERSIONED_NAMESPACE_DECL - -#if defined (NONNATIVE_LONGDOUBLE) -static const ACE_INT16 max_eleven_bit = 0x3ff; -static const ACE_INT16 max_fifteen_bit = 0x3fff; -#endif /* NONNATIVE_LONGDOUBLE */ - -// -// See comments in CDR_Base.inl about optimization cases for swap_XX_array. -// - -void -ACE_CDR::swap_2_array (char const * orig, char* target, size_t n) -{ - // 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 mismatch 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 writing 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. - unsigned long a = * reinterpret_cast<const unsigned long*> (orig); - - unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; - unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8; - - a = (a1 | a2); - - * reinterpret_cast<unsigned long*> (target) = a; -#else - ACE_UINT32 a = * reinterpret_cast<const ACE_UINT32*> (orig); - ACE_UINT32 b = * reinterpret_cast<const ACE_UINT32*> (orig + 4); - - ACE_UINT32 a1 = (a & 0x00ff00ffU) << 8; - ACE_UINT32 b1 = (b & 0x00ff00ffU) << 8; - ACE_UINT32 a2 = (a & 0xff00ff00U) >> 8; - 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. - unsigned long a = * reinterpret_cast<const unsigned long*> (orig); - - unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; - 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 - ACE_UINT32 a = * reinterpret_cast<const ACE_UINT32*> (orig); - ACE_UINT32 b = * reinterpret_cast<const ACE_UINT32*> (orig + 4); - - ACE_UINT32 a1 = (a & 0x00ff00ff) << 8; - ACE_UINT32 b1 = (b & 0x00ff00ff) << 8; - ACE_UINT32 a2 = (a & 0xff00ff00) >> 8; - 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; - // fallthrough - case 2: - ACE_CDR::swap_2 (orig, target); - orig += 2; - target += 2; - // fallthrough - case 1: - ACE_CDR::swap_2 (orig, target); - } -} - -void -ACE_CDR::swap_4_array (char const * orig, char* target, size_t n) -{ - // 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) - { - unsigned long a = * reinterpret_cast<const long*> (orig); - 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 - unsigned long a84 = (a & 0x000000ff000000ffL) << 24; - unsigned long b84 = (b & 0x000000ff000000ffL) << 24; - unsigned long a73 = (a & 0x0000ff000000ff00L) << 8; - unsigned long b73 = (b & 0x0000ff000000ff00L) << 8; - unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8; - unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8; - unsigned long a51 = (a & 0xff000000ff000000L) >> 24; - 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) - { - unsigned long a = * reinterpret_cast<const long*> (orig); - 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 - unsigned long a84 = (a & 0x000000ff000000ffL) << 24; - unsigned long b84 = (b & 0x000000ff000000ffL) << 24; - unsigned long a73 = (a & 0x0000ff000000ff00L) << 8; - unsigned long b73 = (b & 0x0000ff000000ff00L) << 8; - unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8; - unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8; - unsigned long a51 = (a & 0xff000000ff000000L) >> 24; - 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__) - unsigned int a = *reinterpret_cast<const unsigned int*> (orig); - unsigned int b = *reinterpret_cast<const unsigned int*> (orig + 4); - unsigned int c = *reinterpret_cast<const unsigned int*> (orig + 8); - 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 - ACE_UINT32 a = * reinterpret_cast<const ACE_UINT32*> (orig); - ACE_UINT32 b = * reinterpret_cast<const ACE_UINT32*> (orig + 4); - ACE_UINT32 c = * reinterpret_cast<const ACE_UINT32*> (orig + 8); - 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; - // fallthrough - case 2: - ACE_CDR::swap_4 (orig, target); - orig += 4; - target += 4; - // fallthrough - case 1: - ACE_CDR::swap_4 (orig, target); - } -} - -// -// We don't benefit from unrolling in swap_8_array and swap_16_array -// (swap_8 and swap_16 are big enough). -// -void -ACE_CDR::swap_8_array (char const * orig, char* target, size_t n) -{ - // 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; - } -} - -void -ACE_CDR::swap_16_array (char const * orig, char* target, size_t n) -{ - // 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::mb_align (ACE_Message_Block *mb) -{ -#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); -} - -int -ACE_CDR::grow (ACE_Message_Block *mb, size_t minsize) -{ - 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; -} - -size_t -ACE_CDR::total_length (const ACE_Message_Block* begin, - const ACE_Message_Block* end) -{ - 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; -} - -int -ACE_CDR::consolidate (ACE_Message_Block *dst, - const ACE_Message_Block *src) -{ - 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; -} - -#if defined (NONNATIVE_LONGDOUBLE) -ACE_CDR::LongDouble& -ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble::NativeImpl& rhs) -{ - ACE_OS::memset (this->ld, 0, sizeof (this->ld)); - - if (sizeof (rhs) == 8) - { -#if defined (ACE_LITTLE_ENDIAN) - static const size_t byte_zero = 1; - static const size_t byte_one = 0; - char rhs_ptr[16]; - ACE_CDR::swap_8 (reinterpret_cast<const char*> (&rhs), rhs_ptr); -#else - static const size_t byte_zero = 0; - static const size_t byte_one = 1; - const char* rhs_ptr = reinterpret_cast<const char*> (&rhs); -#endif - ACE_INT16 sign = static_cast<ACE_INT16> ( - static_cast<signed char> (rhs_ptr[0])) & 0x8000; - ACE_INT16 exponent = ((rhs_ptr[0] & 0x7f) << 4) | - ((rhs_ptr[1] >> 4) & 0xf); - const char* exp_ptr = reinterpret_cast<const char*> (&exponent); - - // Infinity and NaN have an exponent of 0x7ff in 64-bit IEEE - if (exponent == 0x7ff) - { - exponent = 0x7fff; - } - else if (exponent) // exponent 0 stays 0 in 128-bit - { - exponent = (exponent - max_eleven_bit) + max_fifteen_bit; - } - exponent |= sign; - - // Store the sign bit and exponent - this->ld[0] = exp_ptr[byte_zero]; - this->ld[1] = exp_ptr[byte_one]; - - // Store the mantissa. In an 8 byte double, it is split by - // 4 bits (because of the 12 bits for sign and exponent), so - // we have to shift and or the rhs to get the right bytes. - size_t li = 2; - bool direction = true; - for (size_t ri = 1; ri < sizeof (rhs);) - { - if (direction) - { - this->ld[li] |= ((rhs_ptr[ri] << 4) & 0xf0); - direction = false; - ++ri; - } - else - { - this->ld[li] |= ((rhs_ptr[ri] >> 4) & 0xf); - direction = true; - ++li; - } - } -#if defined (ACE_LITTLE_ENDIAN) - ACE_OS::memcpy (rhs_ptr, this->ld, sizeof (this->ld)); - ACE_CDR::swap_16 (rhs_ptr, this->ld); -#endif - } - else - { - ACE_OS::memcpy(this->ld, - reinterpret_cast<const char*> (&rhs), sizeof (rhs)); - } - return *this; -} - -ACE_CDR::LongDouble& -ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble& rhs) -{ - if (this != &rhs) - *this = rhs; - return *this; -} - -bool -ACE_CDR::LongDouble::operator== (const ACE_CDR::LongDouble &rhs) const -{ - return ACE_OS::memcmp (this->ld, rhs.ld, 16) == 0; -} - -bool -ACE_CDR::LongDouble::operator!= (const ACE_CDR::LongDouble &rhs) const -{ - return ACE_OS::memcmp (this->ld, rhs.ld, 16) != 0; -} - -ACE_CDR::LongDouble::operator ACE_CDR::LongDouble::NativeImpl () const -{ - ACE_CDR::LongDouble::NativeImpl ret = 0.0; - char* lhs_ptr = reinterpret_cast<char*> (&ret); - - if (sizeof (ret) == 8) - { -#if defined (ACE_LITTLE_ENDIAN) - static const size_t byte_zero = 1; - static const size_t byte_one = 0; - char copy[16]; - ACE_CDR::swap_16 (this->ld, copy); -#else - static const size_t byte_zero = 0; - static const size_t byte_one = 1; - const char* copy = this->ld; -#endif - ACE_INT16 exponent = 0; - char* exp_ptr = reinterpret_cast<char*> (&exponent); - exp_ptr[byte_zero] = copy[0]; - exp_ptr[byte_one] = copy[1]; - - ACE_INT16 sign = (exponent & 0x8000); - exponent &= 0x7fff; - - // Infinity and NaN have an exponent of 0x7fff in 128-bit IEEE - if (exponent == 0x7fff) - { - exponent = 0x7ff; - } - else if (exponent) // exponent 0 stays 0 in 64-bit - { - exponent = (exponent - max_fifteen_bit) + max_eleven_bit; - } - exponent = (exponent << 4) | sign; - - // Store the sign and exponent - lhs_ptr[0] = exp_ptr[byte_zero]; - lhs_ptr[1] = exp_ptr[byte_one]; - - // Store the mantissa. In an 8 byte double, it is split by - // 4 bits (because of the 12 bits for sign and exponent), so - // we have to shift and or the rhs to get the right bytes. - size_t li = 1; - bool direction = true; - for (size_t ri = 2; li < sizeof (ret);) { - if (direction) - { - lhs_ptr[li] |= ((copy[ri] >> 4) & 0xf); - direction = false; - ++li; - } - else - { - lhs_ptr[li] |= ((copy[ri] & 0xf) << 4); - direction = true; - ++ri; - } - } - -#if defined (ACE_LITTLE_ENDIAN) - ACE_CDR::swap_8 (lhs_ptr, lhs_ptr); -#endif - } - else - { - ACE_OS::memcpy(lhs_ptr, this->ld, sizeof (ret)); - } - - // This bit of code is unnecessary. However, this code is - // necessary to work around a bug in the gcc 4.1.1 optimizer. - ACE_CDR::LongDouble tmp; - tmp.assign (ret); - - return ret; -} -#endif /* NONNATIVE_LONGDOUBLE */ - - -// ACE_CDR::Fixed - -ACE_CDR::Fixed ACE_CDR::Fixed::from_integer (ACE_CDR::LongLong val) -{ - Fixed f; - f.value_[15] = (val < 0) ? NEGATIVE : POSITIVE; - f.digits_ = 0; - f.scale_ = 0; - bool high = true; - int idx = 15; - while (true) - { - const int mod = static_cast<int> (val % 10); - const unsigned int digit = (mod < 0) ? -mod : mod; - if (high) - f.value_[idx--] |= digit << 4; - else - f.value_[idx] = digit; - high = !high; - ++f.digits_; - if (val >= 10 || val <= -10) - val /= 10; - else - break; - } - - ACE_OS::memset (f.value_, 0, idx + !high); - return f; -} - -ACE_CDR::Fixed ACE_CDR::Fixed::from_integer (ACE_CDR::ULongLong val) -{ - Fixed f; - f.value_[15] = POSITIVE; - f.digits_ = 0; - f.scale_ = 0; - bool high = true; - int idx = 15; - while (true) - { - const unsigned int digit = val % 10; - if (high) - f.value_[idx--] |= digit << 4; - else - f.value_[idx] = digit; - high = !high; - ++f.digits_; - if (val >= 10) - val /= 10; - else - break; - } - - ACE_OS::memset (f.value_, 0, idx + !high); - return f; -} - -ACE_CDR::Fixed ACE_CDR::Fixed::from_floating (LongDouble val) -{ -#if defined ACE_OPENVMS || (defined ACE_VXWORKS && !defined __RTP__) - typedef double BigFloat; -#elif defined NONNATIVE_LONGDOUBLE - typedef LongDouble::NativeImpl BigFloat; -#else - typedef LongDouble BigFloat; -#endif - - Fixed f; - f.digits_ = f.scale_ = 0; - bool negative = false; - if (val < 0) - { - val *= -1; - negative = true; - } - - // How many digits are to the left of the decimal point? - const size_t digits_left = - static_cast<size_t> (1 + ((val > 0) ? std::log10 (val) : 0)); - if (digits_left > MAX_DIGITS) - { - ACE_OS::memset (f.value_, 0, sizeof f.value_); - return f; - } - - f.digits_ = MAX_DIGITS; - f.scale_ = 0; - BigFloat int_part; - BigFloat frac_part = std::modf (val, &int_part); - - // Insert the integer part from least to most significant - int idx = (static_cast<int> (digits_left) + 1) / 2 - 1; - bool high = digits_left % 2; - if (idx >= 0) - f.value_[idx] = 0; - for (size_t i = 0; i < digits_left; ++i, high = !high) - { - const Octet digit = static_cast<Octet> (std::fmod (int_part, 10)); - if (high) - f.value_[idx--] |= digit << 4; - else - f.value_[idx] = digit; - int_part /= 10; - } - - // Insert the fractional part from most to least significant - idx = static_cast<int> (digits_left / 2); - high = digits_left % 2 == 0; - for (size_t i = digits_left; i < MAX_DIGITS; ++i, high = !high) - { - frac_part *= 10; - const Octet digit = static_cast<Octet> (frac_part); - frac_part -= digit; - if (high) - f.value_[idx] = digit << 4; - else - f.value_[idx++] |= digit; - } - - if (frac_part >= 0.5) - ++f; // scale set after here so that ++ applies to the fractional part - - f.scale_ = static_cast<Octet> (MAX_DIGITS - digits_left); - f.normalize (); - f.value_[15] |= negative ? NEGATIVE : POSITIVE; - return f; -} - -void ACE_CDR::Fixed::normalize (UShort min_scale) -{ - if (this->value_[15] & 0xf0 || !this->scale_) - return; - - // Calculate the number of nibbles that can be moved. - ACE_CDR::Octet nibbles = 0; - while (this->digit(nibbles) == 0 && this->scale_ - nibbles > min_scale) - ++nibbles; - - // Move and clear the nibbles. - for (ACE_CDR::Octet idx = nibbles; idx != this->digits_; ++idx) { - this->digit (idx - nibbles, this->digit (idx)); - this->digit (idx, 0); - } - - this->scale_ -= nibbles; - this->digits_ -= nibbles; -} - -ACE_CDR::Fixed ACE_CDR::Fixed::from_string (const char *str) -{ - const bool negative = *str == '-'; - if (negative || *str == '+') - ++str; - - const size_t span = ACE_OS::strspn (str, ".0123456789"); - - Fixed f; - f.value_[15] = negative ? NEGATIVE : POSITIVE; - f.digits_ = 0; - f.scale_ = 0; - - int idx = 15; - bool high = true; - for (size_t iter = span; iter && f.digits_ < MAX_DIGITS; --iter, high = !high) - { - if (str[iter - 1] == '.') - { - f.scale_ = static_cast<Octet> (span - iter); - if (--iter == 0) - break; // skip '.' - } - - const unsigned int digit = str[iter - 1] - '0'; - if (high) - f.value_[idx--] |= digit << 4; - else - f.value_[idx] = digit; - ++f.digits_; - } - - if (!f.scale_ && str[span - f.digits_ - 1] == '.') - f.scale_ = f.digits_; - - if (idx >= 0) - ACE_OS::memset (f.value_, 0, idx + !high); - return f; -} - -ACE_CDR::Fixed ACE_CDR::Fixed::from_octets (const Octet *array, int len, - unsigned int scale) -{ - Fixed f; - ACE_OS::memcpy (f.value_ + 16 - len, array, len); - ACE_OS::memset (f.value_, 0, 16 - len); - f.scale_ = scale; - - f.digits_ = len * 2 - 1; - if (len > 1 && (array[0] >> 4) == 0) - --f.digits_; - - return f; -} - -ACE_CDR::Fixed::operator ACE_CDR::LongLong () const -{ - LongLong val (0); - - for (int i = this->digits_ - 1; i >= this->scale_; --i) - val = 10 * val + this->digit (i); - - if (this->sign ()) - val *= -1; - - return val; -} - -ACE_CDR::Fixed::operator ACE_CDR::LongDouble () const -{ - LongDouble val = ACE_CDR_LONG_DOUBLE_INITIALIZER; - - for (int i = this->digits_ - 1; i >= this->scale_; --i) - ACE_CDR_LONG_DOUBLE_ASSIGNMENT (val, 10 * val + this->digit (i)); - - for (int i = this->scale_ - 1; i >= 0; --i) - val += this->digit (i) * std::pow (10.0l, i - this->scale_); - - if (this->sign ()) - val *= -1; - - return val; -} - -ACE_CDR::Fixed ACE_CDR::Fixed::round (UShort scale) const -{ - Fixed f = *this; - if (scale < f.scale_) - { - for (UShort i = 0; i < f.scale_ - scale; ++i) - f.digit (i, 0); - f.normalize (scale); - const bool negative = f.sign (); - if (negative) - f.value_[15] = (f.value_[15] & 0xf0) | POSITIVE; - if (this->digit (this->scale_ - scale - 1) >= 5) - { - f.scale_ = 0; - ++f; - f.scale_ = static_cast<Octet> (scale); - } - if (negative && !!f) - f.value_[15] = (f.value_[15] & 0xf0) | NEGATIVE; - } - return f; -} - -ACE_CDR::Fixed ACE_CDR::Fixed::truncate (UShort scale) const -{ - Fixed f = *this; - if (scale < f.scale_) - { - for (UShort i = 0; i < f.scale_ - scale; ++i) - f.digit (i, 0); - f.normalize (scale); - if (f.sign ()) - { - f.value_[15] = (f.value_[15] & 0xf0) | POSITIVE; - if (!!f) - f.value_[15] = (f.value_[15] & 0xf0) | NEGATIVE; - } - } - return f; -} - -namespace { - struct BufferAppender - { - BufferAppender (char *buffer, size_t buffer_size) - : buffer_ (buffer), buffer_size_ (buffer_size), idx_ (0) {} - - bool operator+= (char ch) - { - if (this->idx_ == this->buffer_size_ - 1) - return false; - this->buffer_[this->idx_++] = ch; - return true; - } - - char *const buffer_; - const size_t buffer_size_; - size_t idx_; - }; -} - -bool ACE_CDR::Fixed::to_string (char *buffer, size_t buffer_size) const -{ - if (!buffer || buffer_size < 2) - return false; - - const bool negative = this->sign (); - if (negative) - *buffer = '-'; - BufferAppender ba (buffer + negative, buffer_size - negative); - - for (int i = 15 - this->digits_ / 2; i < 16; ++i) - { - const Octet high = this->value_[i] >> 4, low = this->value_[i] & 0xf; - - if ((15 - i) * 2 != this->digits_) - { - if (this->scale_ == 1 + 2 * (15 - i)) - { - if (!ba.idx_ && !(ba += '0')) - return false; - - if (!(ba += '.')) - return false; - } - - if ((ba.idx_ || high) && !(ba += '0' + high)) - return false; - } - - if (this->scale_ && this->scale_ == 2 * (15 - i)) - { - if (!ba.idx_ && !(ba += '0')) - return false; - - if (!(ba += '.')) - return false; - } - - if (i < 15 && (ba.idx_ || low) && !(ba += '0' + low)) - return false; - } - - if (!ba.idx_ && !(ba += '0')) - return false; - - buffer[ba.idx_ + negative] = 0; - return true; -} - -const ACE_CDR::Octet *ACE_CDR::Fixed::to_octets (int &n) const -{ - n = (this->digits_ + 2) / 2; - return 16 - n + reinterpret_cast<const Octet *> (this->value_); -} - -ACE_CDR::Fixed::ConstIterator ACE_CDR::Fixed::pre_add (const ACE_CDR::Fixed &f) -{ - ConstIterator rhs_iter = f.begin (); - if (f.scale_ > this->scale_) - { - const int scale_diff = f.scale_ - this->scale_; - rhs_iter += scale_diff - this->lshift (scale_diff); - } - - if (f.digits_ - f.scale_ > this->digits_ - this->scale_) - { - ACE_CDR::Octet new_digits = this->digits_ + (f.digits_ - f.scale_) - (this->digits_ - this->scale_); - if (new_digits > MAX_DIGITS) - { - for (size_t i = 0; i < static_cast<size_t> (new_digits - MAX_DIGITS); ++i) - this->digit (static_cast<int> (i), 0); - this->normalize (this->scale_ - (new_digits - MAX_DIGITS)); - this->digits_ = MAX_DIGITS; - } - else - this->digits_ = new_digits; - } - return rhs_iter; -} - -ACE_CDR::Fixed &ACE_CDR::Fixed::operator+= (const Fixed &rhs) -{ - if (!this->sign () && rhs.sign ()) - return *this -= -rhs; - - if (this->sign () && !rhs.sign ()) - { - Fixed negated = -*this; - negated -= rhs; - return *this = -negated; - } - - ConstIterator rhs_iter = this->pre_add (rhs); - - Iterator lhs_iter = this->begin (); - if (this->scale_ > rhs.scale_) - lhs_iter += this->scale_ - rhs.scale_; - - bool carry = false; - for (; rhs_iter != rhs.end (); ++lhs_iter, ++rhs_iter) - { - const Octet digit = *lhs_iter + *rhs_iter + carry; - carry = digit > 9; - *lhs_iter = digit - (carry ? 10 : 0); - } - - if (carry) - { - if (this->digits_ < MAX_DIGITS) - { - *lhs_iter = 1; - ++this->digits_; - } - else if (this->scale_) - { - this->digit (0, 0); - this->normalize (this->scale_ - 1); - this->digit (MAX_DIGITS - 1, 1); - } - } - - return *this; -} - -int ACE_CDR::Fixed::lshift (int digits) -{ - int bytes = 0; - for (; bytes < digits / 2; ++bytes) - if (this->value_[bytes]) - break; - - int shifted = 0; - if ((digits % 2) && !(this->value_[bytes] & 0xf0)) - { - for (int i = 0; i < 15 - bytes; ++i) - this->value_[i] = (this->value_[i + bytes] & 0xf) << 4 - | (this->value_[i + bytes + 1] >> 4); - std::memset (this->value_ + 15 - bytes, 0, bytes); - this->value_[15] &= 0xf; - shifted = 2 * bytes + 1; - } - else if (bytes) - { - std::memmove (this->value_, this->value_ + bytes, 16 - bytes); - this->value_[15] &= 0xf; - std::memset (this->value_ + 16 - bytes, 0, bytes - 1); - this->value_[15 - bytes] &= 0xf0; - shifted = 2 * bytes; - } - - this->digits_ += shifted; - if (this->digits_ > MAX_DIGITS) - this->digits_ = MAX_DIGITS; - - this->scale_ += shifted; - if (this->scale_ > MAX_DIGITS) - this->scale_ = MAX_DIGITS; - - return shifted; -} - -ACE_CDR::Fixed &ACE_CDR::Fixed::operator-= (const Fixed &rhs) -{ - if (!this->sign () && rhs.sign ()) - return *this += -rhs; - - if (this->sign () && !rhs.sign ()) - { - Fixed negated = -*this; - negated += rhs; - return *this = -negated; - } - - const Fixed before = *this; - ConstIterator rhs_iter = this->pre_add (rhs); - - Iterator lhs_iter = this->begin (); - if (this->scale_ > rhs.scale_) - lhs_iter += this->scale_ - rhs.scale_; - - bool borrow = false; - for (; rhs_iter != rhs.end (); ++lhs_iter, ++rhs_iter) - if (*rhs_iter + borrow <= *lhs_iter) - { - *lhs_iter -= *rhs_iter + borrow; - borrow = false; - } - else - { - *lhs_iter += 10 - *rhs_iter - borrow; - borrow = true; - } - - while (borrow && lhs_iter != this->end ()) - if (*lhs_iter) - { - --*lhs_iter; - borrow = false; - } - else - *lhs_iter = 9; - - if (borrow) - return *this = -(rhs - before); - - this->ltrim (); - return *this; -} - -ACE_CDR::Fixed &ACE_CDR::Fixed::operator*= (const Fixed &rhs) -{ - if (!this->sign () && rhs.sign ()) - this->value_[15] = (this->value_[15] & 0xf0) | NEGATIVE; - else if (this->sign () && rhs.sign ()) - this->value_[15] = (this->value_[15] & 0xf0) | POSITIVE; - - this->ltrim (); - Fixed right = rhs; - right.ltrim (); - - Octet temp[MAX_DIGITS * 2]; - int carry = 0; - - for (int col = 0; col < this->digits_ + right.digits_; ++col) - { - for (int row = (std::max) (0, col - this->digits_ + 1); - row < (std::min) (col + 1, int (right.digits_)); ++row) - carry += this->digit (col - row) * right.digit (row); - temp[col] = carry % 10; - carry /= 10; - } - - this->digits_ += right.digits_; - this->scale_ += right.scale_; - int digit_offset = 0; - - if (this->digits_ > MAX_DIGITS) - { - digit_offset = this->digits_ - MAX_DIGITS; - this->digits_ = MAX_DIGITS; - if (this->scale_ > digit_offset) - this->scale_ -= digit_offset; - } - - for (int i = 0; i < this->digits_; ++i) - this->digit (i, temp[i + digit_offset]); - - this->ltrim (); - return *this; -} - -ACE_CDR::Fixed &ACE_CDR::Fixed::operator/= (const Fixed &rhs) -{ - if (!rhs) - return *this; - - if (rhs.scale_ && rhs.scale_ <= this->scale_) - this->scale_ -= rhs.scale_; - else if (rhs.scale_) - { - const Octet shifted = this->lshift (rhs.scale_ - this->scale_); - this->scale_ -= shifted; - } - - Fixed rhs_no_scale = rhs; - rhs_no_scale.scale_ = 0; - rhs_no_scale.value_[15] = (rhs_no_scale.value_[15] & 0xf0) | POSITIVE; - rhs_no_scale.ltrim (); - - this->ltrim (); - - if (!this->sign () && rhs.sign ()) - this->value_[15] = (this->value_[15] & 0xf0) | NEGATIVE; - else if (this->sign () && rhs.sign ()) - this->value_[15] = (this->value_[15] & 0xf0) | POSITIVE; - - static const Fixed one = from_integer (LongLong (1)), - two = from_integer (LongLong (2)), - three = from_integer (LongLong (3)), - five = from_integer (LongLong (5)); - - if (rhs_no_scale == one) - return *this; - - // Most sig digit of rhs must be >= 5 - switch (rhs_no_scale.digit (rhs_no_scale.digits_ - 1)) - { - case 1: - return *this = (*this * five) / (rhs_no_scale * five); - case 2: - return *this = (*this * three) / (rhs_no_scale * three); - case 3: - case 4: - return *this = (*this * two) / (rhs_no_scale * two); - default: - break; - } - - const bool neg = this->sign (); - if (neg) - this->value_[15] = (this->value_[15] & 0xf0) | POSITIVE; - - Fixed r; - Fixed q = this->div_helper2 (rhs_no_scale, r); - q.scale_ = this->scale_; - - if (!r) { - *this = neg ? -q : q; - this->normalize (); - return *this; - } - - const int shift = q.lshift (MAX_DIGITS); - if (shift) - { - const Octet scale = r.lshift (shift); - r.scale_ = 0; - Fixed r2; - r = r.div_helper2 (rhs_no_scale, r2); - r.scale_ = scale; - q += r; - } - - *this = neg ? -q : q; - this->normalize (); - return *this; -} - -ACE_CDR::Fixed ACE_CDR::Fixed::div_helper2 (const Fixed &rhs, Fixed &r) const -{ - if (this->digits_ < rhs.digits_) - r = *this; - else if (this->digits_ == rhs.digits_) - if (*this < rhs) - r = *this; - else - { - r = *this - rhs; - return from_integer (LongLong (1)); - } - else if (this->digits_ == rhs.digits_ + 1) - return this->div_helper1 (rhs, r); - else - { - const int dig = this->digits_ - rhs.digits_ - 1; - Fixed top = *this, bot = *this; // split with bot having dig digits - for (int i = 0; i < dig; ++i) - top.digit (i, 0); - for (int i = dig; i < this->digits_; ++i) - bot.digit (i, 0); - bot.digits_ = dig; - top.scale_ += dig; - top.normalize (this->scale_); - - Fixed rtop; - const Fixed qtop = top.div_helper1 (rhs, rtop); - const Fixed qbot = rtop.join (dig, bot).div_helper2 (rhs, r); - return qtop.join (dig, qbot); - } - - return from_integer (); -} - -ACE_CDR::Fixed ACE_CDR::Fixed::div_helper1 (const Fixed &rhs, Fixed &r) const -{ - static const Fixed ten = from_integer (LongLong (10)); - if (*this >= rhs * ten) - return ten + (*this - rhs * ten).div_helper1 (rhs, r); - - int q = (this->digit (this->digits_ - 1) * 10 + - this->digit (this->digits_ - 2)) / rhs.digit (rhs.digits_ - 1); - if (q > 9) - q = 9; - Fixed t = from_integer (LongLong (q)) * rhs; - t.scale_ = this->scale_; - for (int i = 0; i < 2 && t > *this; ++i) - { - --q; - t -= rhs; - } - - r = *this - t; - return from_integer (LongLong (q)); -} - -ACE_CDR::Fixed ACE_CDR::Fixed::join (int digits, const Fixed &bot) const -{ - Fixed res = bot; - res.digits_ = this->digits_ + digits; - for (int i = digits; i < MAX_DIGITS && i - digits < this->digits_; ++i) - res.digit (i, this->digit (i - digits)); - return res; -} - -ACE_CDR::Fixed &ACE_CDR::Fixed::operator++ () -{ - if (this->sign ()) - { - this->value_[15] = (this->value_[15] & 0xf0) | POSITIVE; - if (!!--*this) // decrement and check if result is nonzero - this->value_[15] = (this->value_[15] & 0xf0) | NEGATIVE; - } - else - { - Iterator iter = this->begin (); - iter += this->scale_; - for (; iter != this->end (); ++iter) - { - if (*iter < 9) - { - ++*iter; - return *this; - } - *iter = 0; - } - if (this->digits_ < MAX_DIGITS) - { - ++this->digits_; - *iter = 1; - } - } - return *this; -} - -ACE_CDR::Fixed &ACE_CDR::Fixed::operator-- () -{ - if (this->sign ()) - { - this->value_[15] = (this->value_[15] & 0xf0) | POSITIVE; - ++*this; - this->value_[15] = (this->value_[15] & 0xf0) | NEGATIVE; - } - else - { - Fixed before = *this; - Iterator iter = this->begin (); - iter += this->scale_; - for (; iter != this->end (); ++iter) - { - if (*iter) - { - --*iter; - return *this; - } - *iter = 9; - } - *this = before - from_integer (ULongLong (1)); - } - return *this; -} - -bool ACE_CDR::Fixed::operator! () const -{ - static const Octet ZERO[] = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, POSITIVE}; - return 0 == ACE_OS::memcmp (this->value_, ZERO, sizeof ZERO); -} - -ACE_OSTREAM_TYPE &operator<< (ACE_OSTREAM_TYPE &lhs, const ACE_CDR::Fixed &rhs) -{ - char digits[ACE_CDR::Fixed::MAX_STRING_SIZE]; - rhs.to_string (digits, sizeof digits); - -#ifdef ACE_LACKS_IOSTREAM_TOTALLY - ACE_OS::fputs (digits, &lhs); -#else - lhs << digits; -#endif - return lhs; -} - -#ifndef ACE_LACKS_IOSTREAM_TOTALLY -std::istream &operator>> (std::istream &lhs, ACE_CDR::Fixed &rhs) -{ - double num; - lhs >> num; - ACE_CDR::LongDouble ld; - ACE_CDR_LONG_DOUBLE_ASSIGNMENT (ld, num); - rhs = ACE_CDR::Fixed::from_floating (ld); - return lhs; -} -#endif - -bool ACE_CDR::Fixed::less (const ACE_CDR::Fixed &rhs) const -{ - const Fixed &lhs = *this; - if (lhs.sign () != rhs.sign ()) - return lhs.sign (); - - // signs of lhs and rhs are the same so lhs < rhs reduces to: - // if positive, |lhs| < |rhs| - // if negative, |rhs| < |lhs| - // 'a' will refer to the value left of < and 'b' to the value to the right - const ACE_CDR::Fixed &a = lhs.sign () ? rhs : lhs, - &b = lhs.sign () ? lhs : rhs; - - if (a.scale_ == b.scale_) - return ACE_OS::memcmp (a.value_, b.value_, sizeof a.value_) < 0; - - const int a_int_dig = a.digits_ - a.scale_, b_int_dig = b.digits_ - b.scale_; - - if (a_int_dig > b_int_dig) - { - for (int i = 1; i <= a_int_dig - b_int_dig; ++i) - if (a.digit (a.digits_ - i)) - return false; - } - else if (a_int_dig < b_int_dig) - { - for (int i = 1; i <= b_int_dig - a_int_dig; ++i) - if (b.digit (b.digits_ - i)) - return true; - } - - const int common_frac = (std::min) (a.scale_, b.scale_), - common_dig = (std::min) (a_int_dig, b_int_dig) + common_frac, - a_off = a.scale_ - common_frac, // a's offset (more scale than b) - b_off = b.scale_ - common_frac; // b's offset (more scale than a) - - for (int i = 1; i <= common_dig; ++i) - if (a.digit (a_off + common_dig - i) < b.digit (b_off + common_dig - i)) - return true; - - for (int i = 1; i <= a_off; ++i) - if (a.digit (a_off - i)) - return false; - - for (int i = 1; i <= b_off; ++i) - if (b.digit (b_off - i)) - return true; - - return false; -} - -bool ACE_CDR::Fixed::equal (const ACE_CDR::Fixed &rhs) const -{ - const Fixed &lhs = *this; - if (lhs.sign () != rhs.sign ()) - return false; - - if (lhs.scale_ == rhs.scale_) - return 0 == ACE_OS::memcmp (lhs.value_, rhs.value_, sizeof lhs.value_); - - const ACE_CDR::Fixed &more = (lhs.scale_ > rhs.scale_) ? lhs : rhs, - &fewer = (lhs.scale_ > rhs.scale_) ? rhs : lhs; - - const ACE_CDR::Octet scale_diff = more.scale_ - fewer.scale_; - - ACE_CDR::Fixed::ConstIterator more_iter = more.begin (), - more_end = more.end (); - - for (ACE_CDR::Octet i = 0; i < scale_diff; ++i) - if (more_iter == more_end || *more_iter++) - return false; // digits in more that are missing in fewer must be 0 - - ACE_CDR::Fixed::ConstIterator fewer_iter = fewer.begin (), - fewer_end = fewer.end (); - - while (more_iter != more_end && fewer_iter != fewer_end) - if (*more_iter++ != *fewer_iter++) - return false; // digits in common must match - - while (more_iter != more_end) - if (*more_iter++) - return false; // extra (more significant) digits in more must be 0 - - while (fewer_iter != fewer_end) - if (*fewer_iter++) - return false; // extra (more significant) digits in fewer must be 0 - - return true; -} - -ACE_END_VERSIONED_NAMESPACE_DECL |