Newer
Older
            DOMNodeFilter::FilterAction filterAction = checkFilter(nodeToWrite);
            if ( filterAction == DOMNodeFilter::FILTER_REJECT)
                break;
            if (!lineFeedInTextNodePrinted)
            {
                if(level == 1)
                    printNewLine();
            }
            else
            {
                lineFeedInTextNodePrinted = false;
            }
            printIndent(level);
            //track the line number the current node begins on
            int nodeLine = fCurrentLine;
            // add an entry in the namespace stack
Alberto Massari
committed
            RefHashTableOf<XMLCh>* namespaceMap=NULL;
Gareth Reakes
committed
            if ( filterAction == DOMNodeFilter::FILTER_ACCEPT)
            {
                //           this element    attributes   child elements
                // skip          no              no            yes
                //
                TRY_CATCH_THROW
                (
                // The name has to be representable without any escapes
                    *fFormatter  << XMLFormatter::NoEscapes
                                 << chOpenAngle << nodeName;
                    ,true
                )
                // Output any attributes on this element
                setURCharRef();
                DOMNamedNodeMap *attributes = nodeToWrite->getAttributes();
                int attrCount = attributes->getLength();
Gareth Reakes
committed
                // check if the namespace for the current node is already defined
                const XMLCh* prefix = nodeToWrite->getPrefix();
                const XMLCh* uri = nodeToWrite->getNamespaceURI();
                if(uri && uri[0])
                {
                    if(prefix==0 || prefix[0]==0)
                        prefix=XMLUni::fgZeroLenString;
                    bool bPrefixDeclared=false;
                    for(int i=fNamespaceStack->size()-1;i>=0;i--)
                    {
                        RefHashTableOf<XMLCh>* curNamespaceMap=fNamespaceStack->elementAt(i);
                        const XMLCh* thisUri=curNamespaceMap->get((void*)prefix);
                        if(thisUri && XMLString::equals(thisUri,nodeToWrite->getNamespaceURI()))
                        {
                            bPrefixDeclared=true;
                            break;
                        }
                    }
                    if(!bPrefixDeclared)
                    {
Alberto Massari
committed
                        if(namespaceMap==NULL)
                        {
                            namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);
                            fNamespaceStack->addElement(namespaceMap);
                        }
Gareth Reakes
committed
                        namespaceMap->put((void*)prefix,(XMLCh*)nodeToWrite->getNamespaceURI());
                        *fFormatter  << XMLFormatter::NoEscapes
                                     << chSpace << XMLUni::fgXMLNSString;
Gareth Reakes
committed
                        if(!XMLString::equals(prefix,XMLUni::fgZeroLenString))
                            *fFormatter  << chColon << prefix;
                        *fFormatter  << chEqual << chDoubleQuote
                                     << XMLFormatter::AttrEscapes
                                     << nodeToWrite->getNamespaceURI()
                                     << XMLFormatter::NoEscapes
                                     << chDoubleQuote;
                    }
                }
                bool discard = getFeature(DISCARD_DEFAULT_CONTENT_ID);
                for (int i = 0; i < attrCount; i++)
                {
                    DOMAttrSPtr  attribute = (DOMAttr*)attributes->item(i);
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
                    // Not to be shown to Filter
                    //
                    //"discard-default-content"
                    //    true
                    //    [required] (default)
                    //    Use whatever information available to the implementation
                    //  (i.e. XML schema, DTD, the specified flag on Attr nodes,
                    //  and so on) to decide what attributes and content should be
                    //  discarded or not.
                    //  Note that the specified flag on Attr nodes in itself is
                    //  not always reliable, it is only reliable when it is set
                    //  to false since the only case where it can be set to false
                    //  is if the attribute was created by the implementation.
                    //  The default content won't be removed if an implementation
                    //  does not have any information available.
                    //    false
                    //    [required]
                    //    Keep all attributes and all content.
                    //
                    if (discard && !((DOMAttr*)attribute )->getSpecified())
                        continue;
                    //
                    //  Again the name has to be completely representable. But the
                    //  attribute can have refs and requires the attribute style
                    //  escaping.
                    //
Gareth Reakes
committed
                    // if this attribute is a namespace declaration, add it to the namespace map for the current level
                    const XMLCh* ns = attribute->getNamespaceURI();
                    if (ns != 0 )
                    {
                        if(XMLString::equals(ns, XMLUni::fgXMLNSURIName)) 
Gareth Reakes
committed
                        {
Alberto Massari
committed
                            if(namespaceMap==NULL)
                            {
                                namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);
                                fNamespaceStack->addElement(namespaceMap);
                            }
Gareth Reakes
committed
			                const XMLCh* nsPrefix = attribute->getLocalName();
                            if(XMLString::equals(attribute->getNodeName(),XMLUni::fgXMLNSString))
Gareth Reakes
committed
								nsPrefix = XMLUni::fgZeroLenString;
							if(namespaceMap->containsKey((void*)nsPrefix))
								continue;
Gareth Reakes
committed
                            namespaceMap->put((void*)attribute->getLocalName(),(XMLCh*)attribute->getNodeValue());
                        }
                        else if(!XMLString::equals(ns, XMLUni::fgXMLURIName)) 
Gareth Reakes
committed
                        {
                            // check if the namespace for the current node is already defined
                            const XMLCh* prefix = attribute->getPrefix();
                            if(prefix && prefix[0])
                            {
                                bool bPrefixDeclared=false;
                                for(int i=fNamespaceStack->size()-1;i>=0;i--)
                                {
                                    RefHashTableOf<XMLCh>* curNamespaceMap=fNamespaceStack->elementAt(i);
                                    const XMLCh* thisUri=curNamespaceMap->get((void*)prefix);
                                    if(thisUri && XMLString::equals(thisUri,attribute->getNamespaceURI()))
                                    {
                                        bPrefixDeclared=true;
                                        break;
                                    }
                                }
                                if(!bPrefixDeclared)
                                {
Alberto Massari
committed
                                    if(namespaceMap==NULL)
                                    {
                                        namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);
                                        fNamespaceStack->addElement(namespaceMap);
                                    }
Gareth Reakes
committed
                                    namespaceMap->put((void*)prefix,(XMLCh*)attribute->getNamespaceURI());
                                    *fFormatter  << XMLFormatter::NoEscapes
                                                 << chSpace << XMLUni::fgXMLNSString << chColon << prefix
Gareth Reakes
committed
                                                 << chEqual << chDoubleQuote
                                                 << XMLFormatter::AttrEscapes
                                                 << attribute->getNamespaceURI()
                                                 << XMLFormatter::NoEscapes
                                                 << chDoubleQuote;
                                }
                            }
                        }
                    }
                    *fFormatter  << XMLFormatter::NoEscapes
                                 << chSpace << attribute->getNodeName()
                                 << chEqual << chDoubleQuote
                                 << XMLFormatter::AttrEscapes
                                 << attribute->getNodeValue()
                                 << XMLFormatter::NoEscapes
                                 << chDoubleQuote;
                } // end of for
            } // end of FILTER_ACCEPT
            level++;
            // FILTER_SKIP may start from here
            //
            //  Test for the presence of children, which includes both
            //  text content and nested elements.
            //
Neil Graham
committed
            DOMNodeSPtr child = nodeToWrite->getFirstChild();
            if (child != 0)
            {
                // There are children. Close start-tag, and output children.
                // No escapes are legal here
                if (filterAction == DOMNodeFilter::FILTER_ACCEPT)
                    *fFormatter << XMLFormatter::NoEscapes << chCloseAngle;
                while( child != 0)
                {
                    processNode(child, level);
                    child = child->getNextSibling();
                }
                level--;
                if (filterAction == DOMNodeFilter::FILTER_ACCEPT)
                {
                    //if we are not on the same line as when we started
                    //this node then print a new line and indent
                    if(nodeLine != fCurrentLine)
                    {
                        if (!lineFeedInTextNodePrinted)
                        {
                            printNewLine();
                        }
                        else
                        {
                            lineFeedInTextNodePrinted = false;
                        }
                        if(nodeLine != fCurrentLine && level == 0)
                            printNewLine();
                        printIndent(level);
                    }
                    TRY_CATCH_THROW
                    (
                         *fFormatter << XMLFormatter::NoEscapes << gEndElement
                                     << nodeName << chCloseAngle;
                        ,true
                    )
                }
                level--;
                //
                //  There were no children. Output the short form close of
                //  the element start tag, making it an empty-element tag.
                //
                if (filterAction == DOMNodeFilter::FILTER_ACCEPT)
                {
                    TRY_CATCH_THROW
                        *fFormatter << XMLFormatter::NoEscapes << chForwardSlash << chCloseAngle;
                       , true
                    )
                }
Gareth Reakes
committed
            // remove the namespace map at this level
Alberto Massari
committed
            if(namespaceMap!=NULL)
                fNamespaceStack->removeLastElement();
Gareth Reakes
committed
    case DOMNode::ATTRIBUTE_NODE:
        {
            if (checkFilter(nodeToWrite) != DOMNodeFilter::FILTER_ACCEPT)
                break;
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
            const XMLCh* localName = nodeToWrite->getLocalName();
            // check if this is a DOM Level 1 Node
            if(localName == 0) {
                *fFormatter  << XMLFormatter::NoEscapes
                             << nodeToWrite->getNodeName()
                             << chEqual << chDoubleQuote
                             << XMLFormatter::AttrEscapes
                             << nodeToWrite->getNodeValue()
                             << XMLFormatter::NoEscapes
                             << chDoubleQuote;
            } else {
                *fFormatter  << XMLFormatter::NoEscapes
                             << chOpenCurly << nodeToWrite->getNamespaceURI() 
                             << chCloseCurly << localName
                             << chEqual << chDoubleQuote
                             << XMLFormatter::AttrEscapes
                             << nodeToWrite->getNodeValue()
                             << XMLFormatter::NoEscapes
                             << chDoubleQuote;
            }
            break;
        }
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
    case DOMNode::ENTITY_REFERENCE_NODE:
        {
            //"entities"
            //true
            //[required] (default)
            //Keep EntityReference and Entity nodes in the document.
            //false
            //[optional]
            //Remove all EntityReference and Entity nodes from the document,
            //       putting the entity expansions directly in their place.
            //       Text nodes are into "normal" form.
            //Only EntityReference nodes to non-defined entities are kept in the document.
            if (checkFilter(nodeToWrite) != DOMNodeFilter::FILTER_ACCEPT)
                break;
            if (getFeature(ENTITIES_ID))
            {
                TRY_CATCH_THROW
                (
                    *fFormatter << XMLFormatter::NoEscapes << chAmpersand
                                << nodeName << chSemiColon;
                    , true
                )
            }
            else
            {
                // check if the referenced entity is defined or not
                if (nodeToWrite->getOwnerDocument()->getDoctype()->getEntities()->getNamedItem(nodeName))
                {
Neil Graham
committed
                    DOMNodeSPtr child;
                    for (child = nodeToWrite->getFirstChild();
                    child != 0;
                    child = child->getNextSibling())
                    {
                        processNode(child, level);
                    }
                }
                else
                {
                    TRY_CATCH_THROW
                   (
                        *fFormatter<<XMLFormatter::NoEscapes<<chAmpersand<<nodeName<<chSemiColon;
                        , true
                    )
            }
            break;
        }
        //
        //  feature:split_cdata_sections     occurence of ]]>   unrep-char
        //  ===============================================================
        //          true                        split            split
        //          false                       fails            fails
        //
    case DOMNode::CDATA_SECTION_NODE:
        {
            if (checkFilter(nodeToWrite) != DOMNodeFilter::FILTER_ACCEPT)
                break;
            if(level == 1)
                printNewLine();
            printNewLine();
            printIndent(level);
            if (getFeature(SPLIT_CDATA_SECTIONS_ID))
            {
                // it is fairly complicated and we process this
                // in a separate function.
            }
            else
            {
                // search for "]]>", the node value is not supposed to have this
                if (XMLString::patternMatch((XMLCh* const) nodeValue, gEndCDATA) != -1)
                {
Tinny Ng
committed
                    reportError(nodeToWrite, DOMError::DOM_SEVERITY_FATAL_ERROR, XMLDOMMsg::Writer_NestedCDATA);
                TRY_CATCH_THROW
                (
                    *fFormatter << XMLFormatter::NoEscapes << gStartCDATA << nodeValue << gEndCDATA;
                   , true
                )
        }
    case DOMNode::COMMENT_NODE:
            if (checkFilter(nodeToWrite) != DOMNodeFilter::FILTER_ACCEPT)
                break;
            if(level == 1)
                printNewLine();
            printNewLine();
            printIndent(level);
            TRY_CATCH_THROW
            (
                *fFormatter << XMLFormatter::NoEscapes << gStartComment
                << nodeValue << gEndComment;
                , true
            )
            break;
    case DOMNode::DOCUMENT_TYPE_NODE:  // Not to be shown to Filter
        {
David Abram Cargill
committed
            const DOMDocumentType *doctype = (const DOMDocumentType *)nodeToWrite;
            fFormatter->setEscapeFlags(XMLFormatter::NoEscapes);
            printNewLine();
            printIndent(level);
            (
                *fFormatter << gStartDoctype << nodeName;
                const XMLCh  *id = doctype->getPublicId();
                {
                    *fFormatter << chSpace << gPublic << id << chDoubleQuote;
                    id = doctype->getSystemId();
                    if (id && *id)
                    {
                        *fFormatter << chSpace << chDoubleQuote << id << chDoubleQuote;
                    }
                    else
                    {
                        //
                        // 4.2.2 External Entities
                        // [Definition: If the entity is not internal,
                        //           it is an external entity, declared as follows:]
                        // External Entity Declaration
                        // [75] ExternalID ::= 'SYSTEM' S SystemLiteral
                        //                   | 'PUBLIC' S PubidLiteral S SystemLiteral
                        //
Tinny Ng
committed
                        reportError(nodeToWrite, DOMError::DOM_SEVERITY_FATAL_ERROR, XMLDOMMsg::Writer_NotRecognizedType);
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
                        // systemLiteral not found
                    }
                }
                else
                {
                    id = doctype->getSystemId();
                    if (id && *id)
                    {
                        *fFormatter << chSpace << gSystem << id << chDoubleQuote;
                    }
                }
                id = doctype->getInternalSubset();
                if (id && *id)
                {
                    *fFormatter << chSpace << chOpenSquare << id << chCloseSquare;
                }
                *fFormatter << chCloseAngle;
                , true
            ) // end of TRY_CATCH_THROW
            break;
    case DOMNode::ENTITY_NODE:  // Not to be shown to Filter
            //
            // REVISIT: how does the feature "entities" impact
            // entity node?
            //
            printNewLine();
            printIndent(level);
            fFormatter->setEscapeFlags(XMLFormatter::NoEscapes);
            *fFormatter << gStartEntity    << nodeName;
            const XMLCh * id = ((const DOMEntity*)nodeToWrite)->getPublicId();
            if (id)
                *fFormatter << gPublic << id << chDoubleQuote;
            id = ((const DOMEntity*)nodeToWrite)->getSystemId();
            if (id)
                *fFormatter << gSystem << id << chDoubleQuote;
            id = ((const DOMEntity*)nodeToWrite)->getNotationName();
            if (id)
                *fFormatter << gNotation << id << chDoubleQuote;
            *fFormatter << chCloseAngle;
            break;
    default:
        /***
            This is an implementation specific behaviour, we abort if a user derived class has not dealt with
            this node type.
         ***/
            if(!customNodeSerialize(nodeToWrite, level)) {
                reportError(nodeToWrite, DOMError::DOM_SEVERITY_FATAL_ERROR, XMLDOMMsg::Writer_NotRecognizedType);
                // UnreognizedNodeType;
            }
        }
        break;
David Abram Cargill
committed
bool DOMWriterImpl::customNodeSerialize(const DOMNode* const, int) {
    return false;
}
DOMNodeFilter::FilterAction DOMWriterImpl::checkFilter(const DOMNode* const node) const
{
    if (!fFilter ||
        ((fFilter->getWhatToShow() & (1 << (node->getNodeType() - 1))) == 0))
        return DOMNodeFilter::FILTER_ACCEPT;
    //
    // if and only if there is a filter, and it is interested
    // in the node type, then we pass the node to the filter
    // for examination
    //
    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)
            throw DOMException(DOMException::NOT_FOUND_ERR, 0, fMemoryManager);
PeiYong Zhang
committed
        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))
    //feature name not resolvable
    if (featureId == INVALID_FEATURE_ID)
    {
        if (toThrow)
            throw DOMException(DOMException::NOT_FOUND_ERR, featName, fMemoryManager);
PeiYong Zhang
committed
        return false;
PeiYong Zhang
committed
    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++;
Tinny Ng
committed
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
    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++;
Tinny Ng
committed
    if (errorType == DOMError::DOM_SEVERITY_FATAL_ERROR || !toContinueProcess)
Tinny Ng
committed
        throw toEmit;
    return toContinueProcess;
}
//
//
void DOMWriterImpl::procCdataSection(const XMLCh*   const nodeValue
    /***
     * Append a ']]>' at the end
     */
    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)
        {
            (
                *fFormatter << XMLFormatter::NoEscapes << gStartCDATA << gEndCDATA;
                , true
            )
        }
        else
        {
        if (endTagFound)
        {
            *(nextPtr - offset) = chCloseSquare;   //restore the first ']'
            curPtr = nextPtr;
        }
    }
    return;
}
//
//
void DOMWriterImpl::procUnrepCharInCdataSection(const XMLCh*   const nodeValue
{
    //
    //  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;
David Abram Cargill
committed
    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)
        {
            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
Tinny Ng
committed
            reportError(nodeToWrite, DOMError::DOM_SEVERITY_WARNING, XMLDOMMsg::Writer_NotRepresentChar);
            while (srcPtr < endPtr)
            {
                // Build a char ref for the current char
David Abram Cargill
committed
                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);
    return featuresSupported[2*featureId + (val? 0: 1)];
void DOMWriterImpl::printNewLine()
    if (getFeature(FORMAT_PRETTY_PRINT_ID))
    {
        fCurrentLine++;
        *fFormatter << fNewLineUsed;
Tinny Ng
committed
    }
}
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;
}
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
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;
}