domwriterimpl.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,852 行 · 第 1/5 页
CPP
1,852 行
//SYSTEM "static const XMLCh gSystem[] ={ chLatin_S, chLatin_Y, chLatin_S, chLatin_T, chLatin_E, chLatin_M, chSpace, chDoubleQuote, chNull};//<!ENTITYstatic const XMLCh gStartEntity[] ={ chOpenAngle, chBang, chLatin_E, chLatin_N, chLatin_T, chLatin_I, chLatin_T, chLatin_Y, chSpace, chNull};//NDATA "static const XMLCh gNotation[] ={ chLatin_N, chLatin_D, chLatin_A, chLatin_T, chLatin_A, chSpace, chDoubleQuote, chNull};//Featurestatic const XMLCh gFeature[] ={ chLatin_F, chLatin_e, chLatin_a, chLatin_t, chLatin_u, chLatin_r, chLatin_e, chSpace, chNull};// Can not be set tostatic const XMLCh gCantSet[] ={ chSpace, chLatin_C, chLatin_a, chLatin_n, chSpace, chLatin_n, chLatin_o, chLatin_t, chSpace, chLatin_b, chLatin_e, chSpace, chLatin_s, chLatin_e, chLatin_t, chSpace, chLatin_t, chLatin_o, chSpace, chNull};static const XMLCh gTrue[] ={ chSingleQuote, chLatin_t, chLatin_r, chLatin_u, chLatin_e, chSingleQuote, chLF, chNull};static const XMLCh gFalse[] ={ chSingleQuote, chLatin_f, chLatin_a, chLatin_l, chLatin_s, chLatin_e, chSingleQuote, chLF, chNull};static const XMLByte BOM_utf16be[] = {(XMLByte)0xFE, (XMLByte)0xFF, (XMLByte) 0};static const XMLByte BOM_utf16le[] = {(XMLByte)0xFF, (XMLByte)0xFE, (XMLByte) 0};static const XMLByte BOM_ucs4be[] = {(XMLByte)0x00, (XMLByte)0x00, (XMLByte)0xFE, (XMLByte)0xFF, (XMLByte) 0};static const XMLByte BOM_ucs4le[] = {(XMLByte)0xFF, (XMLByte)0xFE, (XMLByte)0x00, (XMLByte)0x00, (XMLByte) 0};static bool lineFeedInTextNodePrinted = false;static int lastWhiteSpaceInTextNode = 0;//// Notification of the error though error handler//// The application may instruct the engine to abort serialization// by returning "false".//// REVISIT: update the locator ctor once the line#, col#, uri and offset// are available from DOM3 core//// REVISIT: use throwing exception to abort serialization is an interesting// thing here, since the serializer is a recusive function, we// can't use return, obviously. However we may have multiple try/catch// along its way going back to writeNode(). So far we don't come up with a// "short-cut" to go "directly" back.//#define TRY_CATCH_THROW(action, forceToRethrow) \fFormatter->setUnRepFlags(XMLFormatter::UnRep_Fail); \try \{ \ action; \} \catch(TranscodingException const &e) \{ \ if ( !reportError(nodeToWrite \ , DOMError::DOM_SEVERITY_FATAL_ERROR \ , e.getMessage()) || \ forceToRethrow) \ throw e; \}DOMWriterImpl::~DOMWriterImpl(){ fMemoryManager->deallocate(fEncoding);//delete [] fEncoding; fMemoryManager->deallocate(fNewLine);//delete [] fNewLine; delete fNamespaceStack; // we don't own/adopt error handler and filter}DOMWriterImpl::DOMWriterImpl(MemoryManager* const manager):fFeatures(0),fEncoding(0),fNewLine(0),fErrorHandler(0),fFilter(0),fDocumentVersion(XMLUni::fgVersion1_0),fEncodingUsed(0),fNewLineUsed(0),fFormatter(0),fErrorCount(0),fCurrentLine(0),fNamespaceStack(0),fMemoryManager(manager){ fNamespaceStack=new (fMemoryManager) RefVectorOf< RefHashTableOf<XMLCh> >(0,true, fMemoryManager); // // set features to default setting // setFeature(CANONICAL_FORM_ID, false); setFeature(DISCARD_DEFAULT_CONTENT_ID, true ); setFeature(ENTITIES_ID, true ); setFeature(FORMAT_PRETTY_PRINT_ID, false); setFeature(NORMALIZE_CHARACTERS_ID, false); setFeature(SPLIT_CDATA_SECTIONS_ID, true ); setFeature(VALIDATION_ID, false); setFeature(WHITESPACE_IN_ELEMENT_CONTENT_ID, true ); setFeature(BYTE_ORDER_MARK_ID, false); setFeature(XML_DECLARATION, true );}bool DOMWriterImpl::canSetFeature(const XMLCh* const featName , bool state) const{ int featureId = INVALID_FEATURE_ID; return checkFeature(featName, false, featureId) ? canSetFeature(featureId, state) : false;}void DOMWriterImpl::setFeature(const XMLCh* const featName , bool state){ int featureId = INVALID_FEATURE_ID; checkFeature(featName, true, featureId); if (!canSetFeature(featureId, state)) { XMLCh tmpbuf[256]; unsigned int strLen = XMLString::stringLen(gFeature) + XMLString::stringLen(featName) + XMLString::stringLen(gCantSet) + XMLString::stringLen(gFalse); XMLString::copyString(tmpbuf, gFeature); if (strLen < 256) { XMLString::catString(tmpbuf, featName); } else { // truncate the featurename to fit into the 256 buffer XMLString::copyNString(tmpbuf+XMLString::stringLen(gFeature), featName, 200); } XMLString::catString(tmpbuf, gCantSet); XMLString::catString(tmpbuf, state? gTrue : gFalse); throw DOMException(DOMException::NOT_SUPPORTED_ERR, tmpbuf, fMemoryManager); } else setFeature(featureId, state); // // canonical-form and format-pretty-print can not be both set to true // meaning set canonical-form true will automatically set // format-pretty-print to false and vise versa. // if ((featureId == CANONICAL_FORM_ID) && state) setFeature(FORMAT_PRETTY_PRINT_ID, false); if ((featureId == FORMAT_PRETTY_PRINT_ID) && state) setFeature(CANONICAL_FORM_ID, false); return;}bool DOMWriterImpl::getFeature(const XMLCh* const featName) const{ int featureId = INVALID_FEATURE_ID; checkFeature(featName, true, featureId); return getFeature(featureId);}// we don't check the validity of the encoding setvoid DOMWriterImpl::setEncoding(const XMLCh* const encoding){ fMemoryManager->deallocate(fEncoding);//delete [] fEncoding; fEncoding = XMLString::replicate(encoding, fMemoryManager);}const XMLCh* DOMWriterImpl::getEncoding() const{ return fEncoding;}void DOMWriterImpl::setNewLine(const XMLCh* const newLine){ fMemoryManager->deallocate(fNewLine);//delete [] fNewLine; fNewLine = XMLString::replicate(newLine, fMemoryManager);}const XMLCh* DOMWriterImpl::getNewLine() const{ return fNewLine;}void DOMWriterImpl::setErrorHandler(DOMErrorHandler *errorHandler){ fErrorHandler = errorHandler;}DOMErrorHandler* DOMWriterImpl::getErrorHandler() const{ return fErrorHandler;}void DOMWriterImpl::setFilter(DOMWriterFilter *filter){ fFilter = filter;}DOMWriterFilter* DOMWriterImpl::getFilter() const{ return fFilter;}//////bool DOMWriterImpl::writeNode(XMLFormatTarget* const destination , const DOMNode &nodeToWrite){ //init session vars initSession(&nodeToWrite); try { fFormatter = new (fMemoryManager) XMLFormatter(fEncodingUsed ,fDocumentVersion ,destination ,XMLFormatter::NoEscapes ,XMLFormatter::UnRep_CharRef ,fMemoryManager); } catch (const TranscodingException& e) { reportError(&nodeToWrite, DOMError::DOM_SEVERITY_FATAL_ERROR, e.getMessage()); return false; } try { Janitor<XMLFormatter> janName(fFormatter); processNode(&nodeToWrite); destination->flush(); } // // The serialize engine (processNode) throws an exception to abort // serialization if // // . A fatal error occurs which renters the output ill-formed, or // . Instructed by the application's error handler // catch (const TranscodingException&) { destination->flush(); return false; } catch (const XMLDOMMsg::Codes) { destination->flush(); return false; } catch(const OutOfMemoryException&) { throw; } // // DOMSystemException // This exception will be raised in response to any sort of IO or system // error that occurs while writing to the destination. It may wrap an // underlying system exception. // //catch (RuntimeException const &) catch (...) { // REVISIT generate a DOMSystemException wrapping the underlying // exception. destination->flush(); throw; } // // true if node was successfully serialized and // false in case a failure occured and the // failure wasn't canceled by the error handler. // return ((fErrorCount == 0)? true : false);}//// We don't throw DOMSTRING_SIZE_ERR since we are no longer// using DOMString.//XMLCh* DOMWriterImpl::writeToString(const DOMNode &nodeToWrite){ MemBufFormatTarget destination(1023, fMemoryManager); bool retVal; // XMLCh is unicode, assume fEncoding as UTF-16 XMLCh* tempEncoding = fEncoding; fEncoding = (XMLCh*) XMLUni::fgUTF16EncodingString; try { retVal = writeNode(&destination, nodeToWrite); } catch(const OutOfMemoryException&) { throw; } catch (...) { // // there is a possibility that memeory allocation // exception thrown in XMLBuffer class // fEncoding = tempEncoding; return 0; } fEncoding = tempEncoding; return (retVal ? XMLString::replicate((XMLCh*) destination.getRawBuffer(), fMemoryManager) : 0);}void DOMWriterImpl::initSession(const DOMNode* const nodeToWrite){/** * The encoding to use when writing is determined as follows: * If the encoding attribute has been set, that value will be used. * If the encoding attribute is null or empty, * but the item to be written, or * the owner document specified encoding (ie. the "actualEncoding" * from the document) that value will be used. * If neither of the above provides an encoding name, a default encoding of * "UTF-8" will be used. */ fEncodingUsed = gUTF8; if (fEncoding && *fEncoding) { fEncodingUsed = fEncoding; } else { const DOMDocument *docu = (nodeToWrite->getNodeType() == DOMNode::DOCUMENT_NODE)? (const DOMDocument*)nodeToWrite : nodeToWrite->getOwnerDocument(); if (docu) { const XMLCh* tmpEncoding = docu->getEncoding(); if ( tmpEncoding && *tmpEncoding) { fEncodingUsed = tmpEncoding;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?