domwriterimpl.cpp

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

CPP
1,852
字号
    return (DOMNodeFilter::FilterAction) fFilter->acceptNode(node);}bool DOMWriterImpl::checkFeature(const XMLCh* const featName                               , bool               toThrow                               , int&               featureId) const{    // check for null and/or empty feature name    if (!featName || !*featName)    {        if (toThrow)            throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);        return false;    }    featureId = INVALID_FEATURE_ID;    if (XMLString::equals(featName, XMLUni::fgDOMWRTCanonicalForm))        featureId = CANONICAL_FORM_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTDiscardDefaultContent))        featureId = DISCARD_DEFAULT_CONTENT_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTEntities))        featureId = ENTITIES_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTFormatPrettyPrint))        featureId = FORMAT_PRETTY_PRINT_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTNormalizeCharacters))        featureId = NORMALIZE_CHARACTERS_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTSplitCdataSections))        featureId = SPLIT_CDATA_SECTIONS_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTValidation))        featureId = VALIDATION_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTWhitespaceInElementContent))        featureId = WHITESPACE_IN_ELEMENT_CONTENT_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMWRTBOM))        featureId = BYTE_ORDER_MARK_ID;    else if (XMLString::equals(featName, XMLUni::fgDOMXMLDeclaration))        featureId = XML_DECLARATION;    //feature name not resolvable    if (featureId == INVALID_FEATURE_ID)    {        if (toThrow)            throw DOMException(DOMException::NOT_FOUND_ERR, featName, fMemoryManager);        return false;    }    return true;}bool DOMWriterImpl::reportError(const DOMNode* const    errorNode                              , DOMError::ErrorSeverity errorType                              , const XMLCh*   const    errorMsg){    bool toContinueProcess = true;   // default value for no error handler    if (fErrorHandler)    {        DOMLocatorImpl  locator(0, 0, (DOMNode* const) errorNode, 0, 0);        DOMErrorImpl    domError(errorType , errorMsg, &locator);        toContinueProcess = fErrorHandler->handleError(domError);    }    if (errorType != DOMError::DOM_SEVERITY_WARNING)        fErrorCount++;    return toContinueProcess;}bool DOMWriterImpl::reportError(const DOMNode* const    errorNode                              , DOMError::ErrorSeverity errorType                              , XMLDOMMsg::Codes        toEmit){    const unsigned int msgSize = 1023;    XMLCh errText[msgSize + 1];    DOMImplementationImpl::getMsgLoader4DOM()->loadMsg(toEmit, errText, msgSize);    bool toContinueProcess = true;   // default value for no error handler    if (fErrorHandler)    {        DOMLocatorImpl  locator(0, 0, (DOMNode* const) errorNode, 0, 0);        DOMErrorImpl    domError(errorType , errText, &locator);        toContinueProcess = fErrorHandler->handleError(domError);    }    if (errorType != DOMError::DOM_SEVERITY_WARNING)        fErrorCount++;    if (errorType == DOMError::DOM_SEVERITY_FATAL_ERROR || !toContinueProcess)        throw toEmit;    return toContinueProcess;}//////void DOMWriterImpl::procCdataSection(const XMLCh*   const nodeValue                                   , const DOMNode* const nodeToWrite                                   , int level){    /***     * Append a ']]>' at the end     */    int len = XMLString::stringLen(nodeValue);    XMLCh* repNodeValue = (XMLCh*) fMemoryManager->allocate    (        (len + offset + 1) * sizeof(XMLCh)    );//new XMLCh [len + offset + 1];    XMLString::copyString(repNodeValue, nodeValue);    XMLString::catString(repNodeValue, gEndCDATA);    ArrayJanitor<XMLCh>  jName(repNodeValue, fMemoryManager);    XMLCh* curPtr  = (XMLCh*) repNodeValue;    XMLCh* nextPtr = 0;    int    endTagPos = -1;    bool   endTagFound = true;    while (endTagFound)    {        endTagPos = XMLString::patternMatch(curPtr, gEndCDATA);        if (endTagPos != -1)        {            nextPtr = curPtr + endTagPos + offset;  // skip the ']]>'            *(curPtr + endTagPos) = chNull;         //nullify the first ']'            if (endTagPos != len)                reportError(nodeToWrite, DOMError::DOM_SEVERITY_WARNING, XMLDOMMsg::Writer_NestedCDATA);            len = len - endTagPos - offset;        }        else        {            endTagFound = false;        }        /***            to check ]]>]]>        ***/        if (endTagPos == 0)        {            printNewLine();            printIndent(level);            TRY_CATCH_THROW            (                *fFormatter << XMLFormatter::NoEscapes << gStartCDATA << gEndCDATA;                , true            )        }        else        {            procUnrepCharInCdataSection(curPtr, nodeToWrite, level);        }        if (endTagFound)        {            *(nextPtr - offset) = chCloseSquare;   //restore the first ']'            curPtr = nextPtr;        }    }    return;}//////void DOMWriterImpl::procUnrepCharInCdataSection(const XMLCh*   const nodeValue                                              , const DOMNode* const nodeToWrite                                              , int level){    //    //  We have to check each character and see if it could be represented.    //  As long as it can, we just keep up with where we started and how    //  many chars we've checked. When we hit an unrepresentable one, we    //  stop, transcode everything we've collected, then start handling    //  the unrepresentables via char refs. We repeat this until we get all    //  the chars done.    //    const XMLCh*    srcPtr = nodeValue;    const XMLCh*    endPtr = nodeValue +  XMLString::stringLen(nodeValue);    // Set up the common part of the buffer that we build char refs into    XMLCh tmpBuf[32];    tmpBuf[0] = chAmpersand;    tmpBuf[1] = chPound;    tmpBuf[2] = chLatin_x;    while (srcPtr < endPtr)    {        const XMLCh* tmpPtr = srcPtr;        while (tmpPtr < endPtr)        {            if (fFormatter->getTranscoder()->canTranscodeTo(*tmpPtr))                tmpPtr++;            else                break;        }        if (tmpPtr > srcPtr)        {            printNewLine();            printIndent(level);            TRY_CATCH_THROW           (                *fFormatter << XMLFormatter::NoEscapes << gStartCDATA;                , true            )            // We got at least some chars that can be done normally            fFormatter->formatBuf            (                srcPtr                , tmpPtr - srcPtr                , XMLFormatter::NoEscapes                , XMLFormatter::UnRep_Fail            );            TRY_CATCH_THROW            (                *fFormatter << XMLFormatter::NoEscapes << gEndCDATA;                , true            )            // Update the source pointer to our new spot            srcPtr = tmpPtr;        }        else        {            //            //  We hit something unrepresentable. So continue forward doing            //  char refs until we hit something representable again or the            //  end of input.            //            // one warning for consective unrep chars            reportError(nodeToWrite, DOMError::DOM_SEVERITY_WARNING, XMLDOMMsg::Writer_NotRepresentChar);            while (srcPtr < endPtr)            {                // Build a char ref for the current char                XMLString::binToText(*srcPtr, &tmpBuf[3], 8, 16, fMemoryManager);                const unsigned int bufLen = XMLString::stringLen(tmpBuf);                tmpBuf[bufLen] = chSemiColon;                tmpBuf[bufLen+1] = chNull;                // And now call recursively back to our caller to format this                fFormatter->formatBuf                (                    tmpBuf                    , bufLen + 1                    , XMLFormatter::NoEscapes                    , XMLFormatter::UnRep_Fail                );                // Move up the source pointer and break out if needed                srcPtr++;                if (fFormatter->getTranscoder()->canTranscodeTo(*srcPtr))                    break;            }        }    }}void DOMWriterImpl::processNode(const DOMNode* const nodeToWrite){    processNode(nodeToWrite, 0);}bool DOMWriterImpl::canSetFeature(const int featureId                                       , bool      val) const{    return featuresSupported[2*featureId + (val? 0: 1)];}void DOMWriterImpl::printNewLine(){    if (getFeature(FORMAT_PRETTY_PRINT_ID))    {        fCurrentLine++;        *fFormatter << fNewLineUsed;    }}void DOMWriterImpl::printIndent(int level) const{    if (getFeature(FORMAT_PRETTY_PRINT_ID))    {        if (lastWhiteSpaceInTextNode)        {            level -= lastWhiteSpaceInTextNode/2; // two chSpaces equals one indent level            lastWhiteSpaceInTextNode = 0;            // if lastWhiteSpaceInTextNode/2 is greater than level, then            // it means too many spaces have been written to the            // output stream and we can no longer indent properly        }        for(int i = 0; i < level; i++)            *fFormatter << chSpace << chSpace;    }}void DOMWriterImpl::release(){    DOMWriterImpl* writer = (DOMWriterImpl*) this;    delete writer;}void DOMWriterImpl::processBOM(){    // if the feature is not set, don't output bom    if (!getFeature(BYTE_ORDER_MARK_ID))        return;    if ((XMLString::compareIString(fEncoding, XMLUni::fgUTF16LEncodingString)  == 0) ||        (XMLString::compareIString(fEncoding, XMLUni::fgUTF16LEncodingString2) == 0)  )    {        fFormatter->writeBOM(BOM_utf16le, 2);    }    else if ((XMLString::compareIString(fEncoding, XMLUni::fgUTF16BEncodingString)  == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUTF16BEncodingString2) == 0)  )    {        fFormatter->writeBOM(BOM_utf16be, 2);    }    else if ((XMLString::compareIString(fEncoding, XMLUni::fgUTF16EncodingString)  == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUTF16EncodingString2) == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUTF16EncodingString3) == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUTF16EncodingString4) == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUTF16EncodingString5) == 0)  )     {#if defined(ENDIANMODE_LITTLE)            fFormatter->writeBOM(BOM_utf16le, 2);#elif defined(ENDIANMODE_BIG)            fFormatter->writeBOM(BOM_utf16be, 2);#endif    }    else if ((XMLString::compareIString(fEncoding, XMLUni::fgUCS4LEncodingString)  == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUCS4LEncodingString2) == 0)  )    {        fFormatter->writeBOM(BOM_ucs4le, 4);    }    else if ((XMLString::compareIString(fEncoding, XMLUni::fgUCS4BEncodingString)  == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUCS4BEncodingString2) == 0)  )    {        fFormatter->writeBOM(BOM_ucs4be, 4);    }    else if ((XMLString::compareIString(fEncoding, XMLUni::fgUCS4EncodingString)  == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUCS4EncodingString2) == 0) ||             (XMLString::compareIString(fEncoding, XMLUni::fgUCS4EncodingString3) == 0)  )    {#if defined(ENDIANMODE_LITTLE)        fFormatter->writeBOM(BOM_ucs4le, 4);#elif defined(ENDIANMODE_BIG)        fFormatter->writeBOM(BOM_ucs4be, 4);#endif    }    return;}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

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