xmlabstractdoublefloat.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 659 行 · 第 1/2 页

CPP
659
字号
    {        return compareSpecial(lValue, manager);    }    //    // case#4: lValue normal    //         rValue special    //    else    {        return (-1) * compareSpecial(rValue, manager);    }    return 0;}int XMLAbstractDoubleFloat::compareSpecial(const XMLAbstractDoubleFloat* const specialValue                                                                                  , MemoryManager* const manager){    switch (specialValue->fType)    {    case NegINF:        return LESS_THAN;    case PosINF:        return GREATER_THAN;    case NaN:        // NaN is not comparable to any other value        return INDETERMINATE;    default:        XMLCh value1[BUF_LEN+1];        XMLString::binToText(specialValue->fType, value1, 16, 10, manager);        ThrowXMLwithMemMgr1(NumberFormatException                , XMLExcepts::XMLNUM_DBL_FLT_InvalidType                , value1, manager);        //internal error        return 0;    }}////  Assumption: no leading space////  1. The valid char set is "+-.0"//  2. There shall be only one sign at the first position, if there is one.//  3. There shall be only one dot '.', if there is one.////  Return:////  for input comforming to [+]? [0]* '.'? [0]*,//            normalize the input to positive zero string//  for input comforming to '-' [0]* '.'? [0]*,//            normalize the input to negative zero string//  otherwise, do nothing//void XMLAbstractDoubleFloat::normalizeZero(XMLCh* const inData){	// do a quick check	if (!inData  ||		!*inData ||        (XMLString::equals(inData, XMLUni::fgNegZeroString) ) ||        (XMLString::equals(inData, XMLUni::fgPosZeroString) )  )        return;    XMLCh*   srcStr = inData;	bool     minusSeen = false;	// process sign if any	if (*srcStr == chDash)	{		minusSeen = true;		srcStr++;	}	else if (*srcStr == chPlus)	{		srcStr++;	}	// scan the string	bool  dotSeen = false;	bool  isValidStr = true;    XMLCh theChar;	while ((theChar=*srcStr++) && isValidStr)	{		if ( theChar != chPeriod && theChar != chDigit_0 )			isValidStr = false;           		// invalid char        else if (theChar == chPeriod)           // process dot			dotSeen ? isValidStr = false : dotSeen = true;	}	// need not to worry about the memory problem	// since either fgNegZeroString or fgPosZeroString	// is the canonical form (meaning the shortest in length)	// of their category respectively.	if (isValidStr)	{		if (minusSeen)			XMLString::copyString(inData, XMLUni::fgNegZeroString);		else			XMLString::copyString(inData, XMLUni::fgPosZeroString);	}    else    {        // we got to set the sign first, since this string may        // eventaully turn out to be beyond the minimum representable         // number and reduced to -0 or +0.        fSign = minusSeen ? -1 : 1;    }    return;} void XMLAbstractDoubleFloat::normalizeDecimalPoint(char* const toNormal){    // find the locale-specific decimal point delimiter    lconv* lc = localeconv();    char delimiter = *lc->decimal_point;    // replace '.' with the locale-specific decimal point delimiter    if ( delimiter != '.' )    {        char* period = strchr( toNormal, '.' );        if ( period )        {            *period = delimiter;        }    }}/*** * E2-40 * *   3.2.4 float *   3.2.5 double * * . the exponent must be indicated by "E".  *   if the exponent is zero, it must be indicated by "E0".  * * . For the mantissa,  *      the preceding optional "+" sign is prohibited and  *      the decimal point is required.  * * . For the exponent,  *      the preceding optional "+" sign is prohibited.  *      Leading zeroes are prohibited. *       * . Leading and trailing zeroes are prohibited subject to the following:  *   number representations must be normalized such that  *     . there is a single digit, which is non-zero, to the left of the decimal point and *     . at least a single digit to the right of the decimal point. *     . unless the value being represented is zero.  *       The canonical representation for zero is 0.0E0 * ***/     XMLCh* XMLAbstractDoubleFloat::getCanonicalRepresentation(const XMLCh*         const rawData                                                        ,       MemoryManager* const memMgr){    // before anything, let's look for special tokens since that    // breaks the calls to parse below.    if(XMLString::equals(rawData, XMLUni::fgNegINFString) ||        XMLString::equals(rawData, XMLUni::fgPosINFString) ||        XMLString::equals(rawData, XMLUni::fgNaNString)     )    {        return XMLString::replicate(rawData, memMgr);    }    try     {        int    strLen = XMLString::stringLen(rawData);        XMLCh* manStr = (XMLCh*) memMgr->allocate((strLen + 1) * sizeof(XMLCh));        ArrayJanitor<XMLCh> janManStr(manStr, memMgr);        XMLCh* manBuf = (XMLCh*) memMgr->allocate((strLen + 1) * sizeof(XMLCh));        ArrayJanitor<XMLCh> janManBuf(manBuf, memMgr);        XMLCh* expStr = (XMLCh*) memMgr->allocate((strLen + 1) * sizeof(XMLCh));        ArrayJanitor<XMLCh> janExpStr(expStr, memMgr);        XMLCh* retBuffer = (XMLCh*) memMgr->allocate((strLen + 8) * sizeof(XMLCh));        ArrayJanitor<XMLCh> janRetBuffer(retBuffer, memMgr);        retBuffer[0] = 0;        int sign, totalDigits, fractDigits, expValue = 0;        const XMLCh* ePosition = XMLString::findAny(rawData, expSign);        /***         *  parse mantissa and exp separately        ***/        if (!ePosition)        {            XMLBigDecimal::parseDecimal(rawData, manBuf, sign, totalDigits, fractDigits, memMgr);            expValue = 0;        }        else        {            int    manLen = ePosition - rawData;            XMLString::copyNString(manStr, rawData, manLen);            *(manStr + manLen) = chNull;            XMLBigDecimal::parseDecimal(manStr, manBuf, sign, totalDigits, fractDigits, memMgr);            int    expLen = strLen - manLen - 1;            ePosition++;            XMLString::copyNString(expStr, ePosition, expLen);            *(expStr + expLen) = chNull;            expValue = XMLString::parseInt(expStr);         }        if ( (sign == 0) || (totalDigits == 0) )        {            retBuffer[0] = chDigit_0;            retBuffer[1] = chPeriod;            retBuffer[2] = chDigit_0;            retBuffer[3] = chLatin_E;            retBuffer[4] = chDigit_0;            retBuffer[5] = chNull;        }        else        {            XMLCh* retPtr = retBuffer;            if (sign == -1)            {                *retPtr++ = chDash;            }            *retPtr++ = manBuf[0];            *retPtr++ = chPeriod;            //XMLBigDecimal::parseDecimal() will eliminate trailing zeros            // iff there is a decimal points            // eg. 56.7800e0  -> manBuf = 5678, totalDigits = 4, fractDigits = 2            // we print it as 5.678e1            //            // but it wont remove trailing zeros if there is no decimal point.            // eg.  567800e0 -> manBuf = 567800, totalDigits = 6, fractDigits = 0            // we print it 5.67800e5            //            // for the latter, we need to print it as 5.678e5 instead            //            XMLCh* endPtr = manBuf + totalDigits;            if (fractDigits == 0)            {                while(*(endPtr - 1) == chDigit_0)                    endPtr--;            }            int remainLen = endPtr - &(manBuf[1]);            if (remainLen)            {                XMLString::copyNString(retPtr, &(manBuf[1]), remainLen);                retPtr += remainLen;            }            else            {                *retPtr++ = chDigit_0;            }            /***             *              *  . adjust expValue             *                *  new_fractDigits = totalDigits - 1               *  new_expValue = old_expValue + (new_fractDigits - fractDigits)             *             ***/            expValue += (totalDigits - 1) - fractDigits ;            XMLString::binToText(expValue, expStr, strLen, 10, memMgr);            *retPtr++  = chLatin_E;            *retPtr = chNull;            XMLString::catString(&(retBuffer[0]), expStr);        }        janRetBuffer.release();        return retBuffer;    } //try    catch (...)    {        return 0;    }}        /*** * Support for Serialization/De-serialization ***/IMPL_XSERIALIZABLE_NOCREATE(XMLAbstractDoubleFloat)void XMLAbstractDoubleFloat::serialize(XSerializeEngine& serEng){    //REVISIT: may not need to call base since it does nothing    XMLNumber::serialize(serEng);    if (serEng.isStoring())    {        serEng << fValue;        serEng << fType;        serEng << fDataConverted;        serEng << fSign;        serEng.writeString(fRawData);        // Do not serialize fFormattedString    }    else    {        serEng >> fValue;        int type = 0;        serEng >> type;        fType = (LiteralType) type;        serEng >> fDataConverted;        serEng >> fSign;        serEng.readString(fRawData);        // Set it to 0 force it to re-format if needed        fFormattedString = 0;    }}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?