XMLAbstractDoubleFloat.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:10k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: XMLAbstractDoubleFloat.cpp,v 1.2 2001/11/22 21:39:00 peiyongz Exp $
  58.  * $Log: XMLAbstractDoubleFloat.cpp,v $
  59.  * Revision 1.2  2001/11/22 21:39:00  peiyongz
  60.  * Allow "0.0" to be a valid lexcial representation of ZERO.
  61.  *
  62.  * Revision 1.1  2001/11/19 21:33:42  peiyongz
  63.  * Reorganization: Double/Float
  64.  *
  65.  *
  66.  */
  67. // ---------------------------------------------------------------------------
  68. //  Includes
  69. // ---------------------------------------------------------------------------
  70. #include <util/XMLAbstractDoubleFloat.hpp>
  71. #include <util/XMLUniDefs.hpp>
  72. #include <util/NumberFormatException.hpp>
  73. #include <util/Janitor.hpp>
  74. // ---------------------------------------------------------------------------
  75. //  local data member
  76. // ---------------------------------------------------------------------------
  77. static const int BUF_LEN = 64;
  78. static XMLCh value1[BUF_LEN+1];
  79. // ---------------------------------------------------------------------------
  80. //  ctor/dtor
  81. // ---------------------------------------------------------------------------
  82. XMLAbstractDoubleFloat::XMLAbstractDoubleFloat()
  83. :fMantissa(0)
  84. ,fExponent(0)
  85. ,fType(Normal)
  86. {
  87. }
  88. XMLAbstractDoubleFloat::~XMLAbstractDoubleFloat()
  89. {
  90.     if (fMantissa)
  91.         delete fMantissa;
  92.     if (fExponent)
  93.         delete fExponent;
  94. }
  95. void XMLAbstractDoubleFloat::init(const XMLCh* const strValue)
  96. {
  97.     if ((!strValue) || (!*strValue))
  98.         ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_emptyString);
  99.     XMLCh* tmpStrValue = XMLString::replicate(strValue);
  100.     ArrayJanitor<XMLCh> janTmpName(tmpStrValue);
  101.     XMLString::trim(tmpStrValue);
  102.     if (XMLString::compareString(tmpStrValue, XMLUni::fgNegINFString) == 0)
  103.     {
  104.         fType = NegINF;
  105.         return;
  106.     }
  107.     else if (XMLString::compareString(tmpStrValue, XMLUni::fgNegZeroString) == 0)
  108.     {
  109.         fType = NegZero;
  110.         return;
  111.     }
  112.     else if (XMLString::compareString(tmpStrValue, XMLUni::fgNeuralZeroString) == 0)
  113.     {
  114.         fType = NeuralZero;
  115.         return;
  116.     }
  117.     else if (XMLString::compareString(tmpStrValue, XMLUni::fgPosZeroString) == 0)
  118.     {
  119.         fType = PosZero;
  120.         return;
  121.     }
  122.     else if (XMLString::compareString(tmpStrValue, XMLUni::fgPosINFString) == 0)
  123.     {
  124.         fType = PosINF;
  125.         return;
  126.     }
  127.     else if (XMLString::compareString(tmpStrValue, XMLUni::fgNaNString) == 0)
  128.     {
  129.         fType = NaN;
  130.         return;
  131.     }
  132.     //
  133.     // Normal case
  134.     //
  135.     int ePos = 0;
  136.     int tmpStrLen = XMLString::stringLen(tmpStrValue);
  137.     if ((( ePos = XMLString::indexOf(tmpStrValue, chLatin_E)) != -1 ) ||
  138.         (( ePos = XMLString::indexOf(tmpStrValue, chLatin_e)) != -1 )  )
  139.     {
  140.         XMLCh* tmpMantissa = new XMLCh [ePos+1];
  141.         XMLString::subString(tmpMantissa, tmpStrValue, 0, ePos);
  142.         ArrayJanitor<XMLCh> janMantissa(tmpMantissa);
  143.         fMantissa = new XMLBigDecimal(tmpMantissa);
  144.         //
  145.         // 1234.56E78
  146.         //
  147.         if ( ePos < tmpStrLen - 1)
  148.         {
  149.             XMLCh* tmpExponent = new XMLCh [tmpStrLen - ePos];
  150.             XMLString::subString(tmpExponent, tmpStrValue, ePos + 1, tmpStrLen);
  151.             ArrayJanitor<XMLCh> janExponent(tmpExponent);
  152.             fExponent = new XMLBigInteger(tmpExponent);
  153.         }
  154.         //
  155.         // 1234.56E
  156.         //
  157.         else
  158.         {
  159.             ThrowXML1(NumberFormatException
  160.                     , XMLExcepts::XMLNUM_DBL_FLT_No_Exponent
  161.                     , strValue);
  162.         }
  163.     }
  164.     else
  165.     {
  166.         fMantissa = new XMLBigDecimal(tmpStrValue);
  167.         fExponent = new XMLBigInteger(XMLUni::fgZeroString);
  168.     }
  169.     checkBoundary(tmpStrValue);
  170. }
  171. //
  172. // Add the 'E' as necessary
  173. // The caller needs to de-allocate the memory allocated by this function
  174. // Deallocate the memory allocated by XMLBigInteger
  175. //
  176. XMLCh*  XMLAbstractDoubleFloat::toString() const
  177. {
  178.     switch (fType)
  179.     {
  180.     case NegINF:
  181.         return XMLString::replicate(XMLUni::fgNegINFString);
  182.     case NegZero:
  183.         return XMLString::replicate(XMLUni::fgNegZeroString);
  184.     case NeuralZero:
  185.         return XMLString::replicate(XMLUni::fgNeuralZeroString);
  186.     case PosZero:
  187.         return XMLString::replicate(XMLUni::fgPosZeroString);
  188.     case PosINF:
  189.         return XMLString::replicate(XMLUni::fgPosINFString);
  190.     case NaN:
  191.         return XMLString::replicate(XMLUni::fgNaNString);
  192.     case Normal:
  193.         XMLCh *ret_mantissa;
  194.         ret_mantissa = fMantissa->toString();
  195.         if (fExponent)
  196.         {
  197.             XMLCh *ret_exponent = fExponent->toString();
  198.             XMLCh *ret_val = new XMLCh [ XMLString::stringLen(ret_mantissa) +
  199.                                          XMLString::stringLen(ret_exponent) + 2];
  200.             *ret_val = 0;
  201.             XMLString::catString(ret_val, ret_mantissa);
  202.             XMLString::catString(ret_val, XMLUni::fgEString);
  203.             XMLString::catString(ret_val, ret_exponent);
  204.             delete [] ret_mantissa;
  205.             delete [] ret_exponent;
  206.             return ret_val;
  207.         }
  208.         else
  209.             return ret_mantissa;
  210.         break;
  211.     default:
  212.         XMLString::binToText(fType, value1, 16, 10);
  213.         ThrowXML1(NumberFormatException
  214.                 , XMLExcepts::XMLNUM_DBL_FLT_InvalidType
  215.                 , value1);
  216.     };
  217.     return (XMLCh*) 0;
  218. }
  219. int XMLAbstractDoubleFloat::getSign() const
  220. {
  221.     return fMantissa->getSign();
  222. }
  223. //
  224. //
  225. //
  226. int XMLAbstractDoubleFloat::compareValues(const XMLAbstractDoubleFloat* const lValue
  227.                                         , const XMLAbstractDoubleFloat* const rValue)
  228. {
  229.     //
  230.     // case#1: lValue normal
  231.     //         rValue normal
  232.     //
  233.     if ((!lValue->isSpecialValue()) &&
  234.         (!rValue->isSpecialValue())  )
  235.     {
  236.         //
  237.         // if we use fValue to compare two
  238.         // sequences "12.3456E4" and "1234.56E2",
  239.         // they are _NOT_ the same. so we ask
  240.         // BigDecimal to compare.
  241.         //
  242.         XMLBigDecimal ldv = XMLBigDecimal(*(lValue->fMantissa), lValue->fExponent->intValue());
  243.         XMLBigDecimal rdv = XMLBigDecimal(*(rValue->fMantissa), rValue->fExponent->intValue());
  244.         return XMLBigDecimal::compareValues(&ldv, &rdv);
  245.     }
  246.     //
  247.     // case#2: lValue special
  248.     //         rValue special
  249.     //
  250.     else
  251.     if ((lValue->isSpecialValue()) &&
  252.         (rValue->isSpecialValue())  )
  253.     {
  254.         if (lValue->fType == rValue->fType)
  255.             return 0;
  256.         else
  257.             return (lValue->fType > rValue->fType ? 1 : -1);
  258.     }
  259.     //
  260.     // case#3: lValue special
  261.     //         rValue normal
  262.     //
  263.     else
  264.     if ((lValue->isSpecialValue()) &&
  265.         (!rValue->isSpecialValue())  )
  266.     {
  267.         return compareSpecial(lValue, rValue);
  268.     }
  269.     //
  270.     // case#4: lValue normal
  271.     //         rValue special
  272.     //
  273.     else
  274.     {
  275.         return (-1) * compareSpecial(rValue, lValue);
  276.     }
  277.     return 0;
  278. }
  279. int XMLAbstractDoubleFloat::compareSpecial(const XMLAbstractDoubleFloat* const specialValue
  280.                                          , const XMLAbstractDoubleFloat* const normalValue)
  281. {
  282.     switch (specialValue->fType)
  283.     {
  284.     case NegINF:
  285.         return -1;
  286.     case NegZero:
  287.     case NeuralZero:
  288.     case PosZero:
  289.         return (normalValue->getSign() > 0 ? -1 : 1);
  290.     case PosINF:
  291.         return 1;
  292.     case NaN:
  293.         return 1;
  294.     default:
  295.         XMLString::binToText(specialValue->fType, value1, 16, 10);
  296.         ThrowXML1(NumberFormatException
  297.                 , XMLExcepts::XMLNUM_DBL_FLT_InvalidType
  298.                 , value1);
  299.         //internal error
  300.         return 0;
  301.     }
  302. }