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 + -
显示快捷键?