XMLAbstractDoubleFloat.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:13k
源码类别:

词法分析

开发平台:

Visual 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.13 2003/05/16 06:01:52 knoaman Exp $
  58.  * $Log: XMLAbstractDoubleFloat.cpp,v $
  59.  * Revision 1.13  2003/05/16 06:01:52  knoaman
  60.  * Partial implementation of the configurable memory manager.
  61.  *
  62.  * Revision 1.12  2003/05/15 19:07:46  knoaman
  63.  * Partial implementation of the configurable memory manager.
  64.  *
  65.  * Revision 1.11  2003/03/12 20:45:46  peiyongz
  66.  * format string for value converted to Zero.
  67.  *
  68.  * Revision 1.10  2003/03/10 20:55:58  peiyongz
  69.  * Schema Errata E2-40 double/float
  70.  *
  71.  * Revision 1.9  2003/02/02 23:54:43  peiyongz
  72.  * getFormattedString() added to return original and converted value.
  73.  *
  74.  * Revision 1.8  2003/01/30 21:55:22  tng
  75.  * Performance: create getRawData which is similar to toString but return the internal data directly, user is not required to delete the returned memory.
  76.  *
  77.  * Revision 1.7  2002/12/11 00:20:02  peiyongz
  78.  * Doing businesss in value space. Converting out-of-bound value into special values.
  79.  *
  80.  * Revision 1.6  2002/11/04 15:22:05  tng
  81.  * C++ Namespace Support.
  82.  *
  83.  * Revision 1.5  2002/09/24 19:51:24  tng
  84.  * Performance: use XMLString::equals instead of XMLString::compareString
  85.  *
  86.  * Revision 1.4  2002/05/03 16:05:45  peiyongz
  87.  * Bug 7341: Missing newline at end of util and DOM source files,
  88.  * patch from Martin Kalen.
  89.  *
  90.  * Revision 1.3  2002/03/06 19:13:12  peiyongz
  91.  * Patch: more valid lexcial representation for positive/negative zero
  92.  *
  93.  * Revision 1.2  2002/03/01 18:47:37  peiyongz
  94.  * fix: more valid lexcial representation forms for "neural zero"
  95.  *
  96.  * Revision 1.1.1.1  2002/02/01 22:22:14  peiyongz
  97.  * sane_include
  98.  *
  99.  * Revision 1.2  2001/11/22 21:39:00  peiyongz
  100.  * Allow "0.0" to be a valid lexcial representation of ZERO.
  101.  *
  102.  * Revision 1.1  2001/11/19 21:33:42  peiyongz
  103.  * Reorganization: Double/Float
  104.  *
  105.  *
  106.  */
  107. // ---------------------------------------------------------------------------
  108. //  Includes
  109. // ---------------------------------------------------------------------------
  110. #include <xercesc/util/XMLAbstractDoubleFloat.hpp>
  111. #include <xercesc/util/XMLUniDefs.hpp>
  112. #include <xercesc/util/NumberFormatException.hpp>
  113. #include <xercesc/util/XMLString.hpp>
  114. #include <xercesc/util/Janitor.hpp>
  115. XERCES_CPP_NAMESPACE_BEGIN
  116. // ---------------------------------------------------------------------------
  117. //  local data member
  118. // ---------------------------------------------------------------------------
  119. static const int BUF_LEN = 64;
  120. static XMLCh value1[BUF_LEN+1];
  121. // ---------------------------------------------------------------------------
  122. //  ctor/dtor
  123. // ---------------------------------------------------------------------------
  124. XMLAbstractDoubleFloat::XMLAbstractDoubleFloat(MemoryManager* const manager)
  125. : fValue(0)
  126. , fType(Normal)
  127. , fDataConverted(false)
  128. , fSign(0)
  129. , fRawData(0)
  130. , fFormattedString(0)
  131. , fMemoryManager(manager)
  132. {
  133. }
  134. XMLAbstractDoubleFloat::~XMLAbstractDoubleFloat()
  135. {
  136.      fMemoryManager->deallocate(fRawData);//delete [] fRawData;
  137.      fMemoryManager->deallocate(fFormattedString);//delete [] fFormattedString;
  138. }
  139. void XMLAbstractDoubleFloat::init(const XMLCh* const strValue)
  140. {
  141.     if ((!strValue) || (!*strValue))
  142.         ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_emptyString);
  143.     fRawData = XMLString::replicate(strValue, fMemoryManager);   // preserve the raw data form
  144.     XMLCh* tmpStrValue = XMLString::replicate(strValue, fMemoryManager);
  145.     ArrayJanitor<XMLCh> janTmpName(tmpStrValue, fMemoryManager);
  146.     XMLString::trim(tmpStrValue);
  147.     normalizeZero(tmpStrValue);
  148.     if (XMLString::equals(tmpStrValue, XMLUni::fgNegINFString) )
  149.     {
  150.         fType = NegINF;
  151.         fSign = -1;
  152.     }
  153.     else if (XMLString::equals(tmpStrValue, XMLUni::fgPosINFString) )
  154.     {
  155.         fType = PosINF;
  156.         fSign = 1;
  157.     }
  158.     else if (XMLString::equals(tmpStrValue, XMLUni::fgNaNString) )
  159.     {
  160.         fType = NaN;
  161.         fSign = 1;
  162.     }
  163.     else
  164.         //
  165.         // Normal case
  166.         //
  167.     {
  168.         checkBoundary(tmpStrValue);
  169.     }
  170. }
  171. //
  172. // 
  173. //
  174. XMLCh*  XMLAbstractDoubleFloat::toString() const
  175. {
  176.     // Return data using global operator new
  177.     return XMLString::replicate(fRawData);
  178. }
  179. XMLCh*  XMLAbstractDoubleFloat::getRawData() const
  180. {
  181.     return fRawData;
  182. }
  183. const XMLCh*  XMLAbstractDoubleFloat::getFormattedString() const
  184. {
  185.     if (!fDataConverted)
  186.     {
  187.         return fRawData;
  188.     }
  189.     else 
  190.     {
  191.         if (!fFormattedString)    
  192.         {
  193.             XMLAbstractDoubleFloat *temp = (XMLAbstractDoubleFloat *) this;
  194.             temp->formatString();
  195.         }
  196.         return fFormattedString;           
  197.     }
  198. }
  199. void XMLAbstractDoubleFloat::formatString()
  200. {
  201.     unsigned int rawDataLen = XMLString::stringLen(fRawData);
  202.     fFormattedString = (XMLCh*) fMemoryManager->allocate
  203.     (
  204.         (rawDataLen + 8) * sizeof(XMLCh)
  205.     );//new XMLCh [ rawDataLen + 8];
  206.     for (unsigned int i = 0; i < rawDataLen + 8; i++)
  207.         fFormattedString[i] = chNull;
  208.     XMLString::copyString(fFormattedString, fRawData);
  209.     fFormattedString[rawDataLen] = chSpace;
  210.     fFormattedString[rawDataLen + 1] = chOpenParen;
  211.     switch (fType)
  212.     {
  213.     case NegINF:       
  214.         XMLString::catString(fFormattedString, XMLUni::fgNegINFString);
  215.         break;
  216.     case PosINF:
  217.         XMLString::catString(fFormattedString, XMLUni::fgPosINFString);
  218.         break;
  219.     case NaN:
  220.         XMLString::catString(fFormattedString, XMLUni::fgNaNString);
  221.         break;
  222.     default:
  223.         // its zero
  224.         XMLString::catString(fFormattedString, XMLUni::fgPosZeroString);
  225.         break;
  226.     }
  227.     fFormattedString[XMLString::stringLen(fFormattedString)] = chCloseParen;
  228. }
  229. int XMLAbstractDoubleFloat::getSign() const
  230. {
  231.     return fSign;
  232. }
  233. //
  234. //
  235. //
  236. int XMLAbstractDoubleFloat::compareValues(const XMLAbstractDoubleFloat* const lValue
  237.                                         , const XMLAbstractDoubleFloat* const rValue)
  238. {
  239.     //
  240.     // case#1: lValue normal
  241.     //         rValue normal
  242.     //
  243.     if ((!lValue->isSpecialValue()) &&
  244.         (!rValue->isSpecialValue())  )
  245.     {
  246.         if (lValue->fValue == rValue->fValue)
  247.             return EQUAL;
  248.         else
  249.             return (lValue->fValue > rValue->fValue) ? GREATER_THAN : LESS_THAN;
  250.     }
  251.     //
  252.     // case#2: lValue special
  253.     //         rValue special
  254.     //
  255.     // Schema Errata E2-40
  256.     // 
  257.     // Positive Infinity is greater than all other non-NAN value.
  258.     // Nan equals itself but is not comparable with (neither greater than nor less than)
  259.     //     any other value in the value space
  260.     // Negative Infinity is less than all other non-NAN values.
  261.     //
  262.     else
  263.     if ((lValue->isSpecialValue()) &&
  264.         (rValue->isSpecialValue())  )
  265.     {
  266.         if (lValue->fType == rValue->fType)
  267.             return EQUAL;
  268.         else
  269.         {
  270.             if ((lValue->fType == NaN) ||
  271.                 (rValue->fType == NaN)  )
  272.             {
  273.                 return INDETERMINATE;
  274.             }
  275.             else
  276.             {
  277.                 return (lValue->fType > rValue->fType) ? GREATER_THAN : LESS_THAN;
  278.             }
  279.         }
  280.     }
  281.     //
  282.     // case#3: lValue special
  283.     //         rValue normal
  284.     //
  285.     else
  286.     if ((lValue->isSpecialValue()) &&
  287.         (!rValue->isSpecialValue())  )
  288.     {
  289.         return compareSpecial(lValue, rValue);
  290.     }
  291.     //
  292.     // case#4: lValue normal
  293.     //         rValue special
  294.     //
  295.     else
  296.     {
  297.         return (-1) * compareSpecial(rValue, lValue);
  298.     }
  299.     return 0;
  300. }
  301. int XMLAbstractDoubleFloat::compareSpecial(const XMLAbstractDoubleFloat* const specialValue
  302.                                          , const XMLAbstractDoubleFloat* const normalValue)
  303. {
  304.     switch (specialValue->fType)
  305.     {
  306.     case NegINF:
  307.         return LESS_THAN;
  308.     case PosINF:
  309.         return GREATER_THAN;
  310.     case NaN:
  311.         // NaN is not comparable to any other value
  312.         return INDETERMINATE;
  313.     default:
  314.         XMLString::binToText(specialValue->fType, value1, 16, 10);
  315.         ThrowXML1(NumberFormatException
  316.                 , XMLExcepts::XMLNUM_DBL_FLT_InvalidType
  317.                 , value1);
  318.         //internal error
  319.         return 0;
  320.     }
  321. }
  322. //
  323. //  Assumption: no leading space
  324. //
  325. //  1. The valid char set is "+-.0"
  326. //  2. There shall be only one sign at the first position, if there is one.
  327. //  3. There shall be only one dot '.', if there is one.
  328. //
  329. //  Return:
  330. //
  331. //  for input comforming to [+]? [0]* '.'? [0]*,
  332. //            normalize the input to positive zero string
  333. //  for input comforming to '-' [0]* '.'? [0]*,
  334. //            normalize the input to negative zero string
  335. //  otherwise, do nothing
  336. //
  337. void XMLAbstractDoubleFloat::normalizeZero(XMLCh* const inData)
  338. {
  339. // do a quick check
  340. if (!inData  ||
  341. !*inData ||
  342.         (XMLString::equals(inData, XMLUni::fgNegZeroString) ) ||
  343.         (XMLString::equals(inData, XMLUni::fgPosZeroString) )  )
  344.         return;
  345.     XMLCh*   srcStr = inData;
  346. bool     minusSeen = false;
  347. // process sign if any
  348. if (*srcStr == chDash)
  349. {
  350. minusSeen = true;
  351. srcStr++;
  352. }
  353. else if (*srcStr == chPlus)
  354. {
  355. srcStr++;
  356. }
  357. // scan the string
  358. bool  dotSeen = false;
  359. bool  isValidStr = true;
  360.     XMLCh theChar;
  361. while ((theChar=*srcStr++) && isValidStr)
  362. {
  363. if ( theChar != chPeriod && theChar != chDigit_0 )
  364. isValidStr = false;            // invalid char
  365.         else if (theChar == chPeriod)           // process dot
  366. dotSeen ? isValidStr = false : dotSeen = true;
  367. }
  368. // need not to worry about the memory problem
  369. // since either fgNegZeroString or fgPosZeroString
  370. // is the canonical form (meaning the shortest in length)
  371. // of their category respectively.
  372. if (isValidStr)
  373. {
  374. if (minusSeen)
  375. XMLString::copyString(inData, XMLUni::fgNegZeroString);
  376. else
  377. XMLString::copyString(inData, XMLUni::fgPosZeroString);
  378. }
  379.     else
  380.     {
  381.         // we got to set the sign first, since this string may
  382.         // eventaully turn out to be beyond the minimum representable 
  383.         // number and reduced to -0 or +0.
  384.         fSign = minusSeen ? -1 : 1;
  385.     }
  386.     return;
  387. XERCES_CPP_NAMESPACE_END