xmlscanner.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,855 行 · 第 1/5 页
CPP
1,855 行
emitError ( XMLErrs::XMLException_Fatal , e.getType() , e.getMessage() ); return; } } } catch(const XMLException& excToCatch) { // For any other XMLException, // emit the error and catch any user exception thrown from here. fInException = true; if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning) emitError ( XMLErrs::XMLException_Warning , excToCatch.getType() , excToCatch.getMessage() ); else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal) emitError ( XMLErrs::XMLException_Fatal , excToCatch.getType() , excToCatch.getMessage() ); else emitError ( XMLErrs::XMLException_Error , excToCatch.getType() , excToCatch.getMessage() ); return; } Janitor<InputSource> janSrc(srcToUse); scanDocument(*srcToUse);}void XMLScanner::scanDocument( const char* const systemId){ // We just delegate this to the XMLCh version after transcoding XMLCh* tmpBuf = XMLString::transcode(systemId, fMemoryManager); ArrayJanitor<XMLCh> janBuf(tmpBuf, fMemoryManager); scanDocument(tmpBuf);}// This method begins a progressive parse. It scans through the prolog and// returns a token to be used on subsequent scanNext() calls. If the return// value is true, then the token is legal and ready for further use. If it// returns false, then the scan of the prolog failed and the token is not// going to work on subsequent scanNext() calls.bool XMLScanner::scanFirst( const XMLCh* const systemId , XMLPScanToken& toFill){ // First we try to parse it as a URL. If that fails, we assume its // a file and try it that way. InputSource* srcToUse = 0; try { // Create a temporary URL. Since this is the primary document, // it has to be fully qualified. If not, then assume we are just // mistaking a file for a URL. XMLURL tmpURL(fMemoryManager); if (XMLURL::parse(systemId, tmpURL)) { if (tmpURL.isRelative()) { if (!fStandardUriConformant) srcToUse = new (fMemoryManager) LocalFileInputSource(systemId, fMemoryManager); else { // since this is the top of the try/catch, cannot call ThrowXMLwithMemMgr // emit the error directly MalformedURLException e(__FILE__, __LINE__, XMLExcepts::URL_NoProtocolPresent, fMemoryManager); fInException = true; emitError ( XMLErrs::XMLException_Fatal , e.getType() , e.getMessage() ); return false; } } else { if (fStandardUriConformant && tmpURL.hasInvalidChar()) { MalformedURLException e(__FILE__, __LINE__, XMLExcepts::URL_MalformedURL, fMemoryManager); fInException = true; emitError ( XMLErrs::XMLException_Fatal , e.getType() , e.getMessage() ); return false; } srcToUse = new (fMemoryManager) URLInputSource(tmpURL, fMemoryManager); } } else { if (!fStandardUriConformant) srcToUse = new (fMemoryManager) LocalFileInputSource(systemId, fMemoryManager); else { // since this is the top of the try/catch, cannot call ThrowXMLwithMemMgr // emit the error directly // lazy bypass ... since all MalformedURLException are fatal, no need to check the type MalformedURLException e(__FILE__, __LINE__, XMLExcepts::URL_MalformedURL); fInException = true; emitError ( XMLErrs::XMLException_Fatal , e.getType() , e.getMessage() ); return false; } } } catch(const XMLException& excToCatch) { // For any other XMLException, // emit the error and catch any user exception thrown from here. fInException = true; if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning) emitError ( XMLErrs::XMLException_Warning , excToCatch.getType() , excToCatch.getMessage() ); else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal) emitError ( XMLErrs::XMLException_Fatal , excToCatch.getType() , excToCatch.getMessage() ); else emitError ( XMLErrs::XMLException_Error , excToCatch.getType() , excToCatch.getMessage() ); return false; } Janitor<InputSource> janSrc(srcToUse); return scanFirst(*srcToUse, toFill);}bool XMLScanner::scanFirst( const char* const systemId , XMLPScanToken& toFill){ // We just delegate this to the XMLCh version after transcoding XMLCh* tmpBuf = XMLString::transcode(systemId, fMemoryManager); ArrayJanitor<XMLCh> janBuf(tmpBuf, fMemoryManager); return scanFirst(tmpBuf, toFill);}bool XMLScanner::scanFirst( const InputSource& src , XMLPScanToken& toFill){ // Bump up the sequence id for this new scan cycle. This will invalidate // any previous tokens we've returned. fSequenceId++; // Reset the scanner and its plugged in stuff for a new run. This // resets all the data structures, creates the initial reader and // pushes it on the stack, and sets up the base document path scanReset(src); // If we have a document handler, then call the start document if (fDocHandler) fDocHandler->startDocument(); try { // Scan the prolog part, which is everything before the root element // including the DTD subsets. This is all that is done on the scan // first. scanProlog(); // If we got to the end of input, then its not a valid XML file. // Else, go on to scan the content. if (fReaderMgr.atEOF()) { emitError(XMLErrs::EmptyMainEntity); } } // NOTE: // // In all of the error processing below, the emitError() call MUST come // before the flush of the reader mgr, or it will fail because it tries // to find out the position in the XML source of the error. catch(const XMLErrs::Codes) { // This is a 'first failure' exception so reset and return a failure fReaderMgr.reset(); return false; } catch(const XMLValid::Codes) { // This is a 'first fatal error' type exit, so reset and reuturn failure fReaderMgr.reset(); return false; } catch(const XMLException& excToCatch) { // Emit the error and catch any user exception thrown from here. Make // sure in all cases we flush the reader manager. fInException = true; try { if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning) emitError ( XMLErrs::XMLException_Warning , excToCatch.getType() , excToCatch.getMessage() ); else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal) emitError ( XMLErrs::XMLException_Fatal , excToCatch.getType() , excToCatch.getMessage() ); else emitError ( XMLErrs::XMLException_Error , excToCatch.getType() , excToCatch.getMessage() ); } catch(const OutOfMemoryException&) { throw; } catch(...) { // Reset and rethrow the user error fReaderMgr.reset(); throw; } // Reset and return a failure fReaderMgr.reset(); return false; } catch(const OutOfMemoryException&) { throw; } catch(...) { // Reset and rethrow original error fReaderMgr.reset(); throw; } // Fill in the caller's token to make it legal and return success toFill.set(fScannerId, fSequenceId); return true;}void XMLScanner::scanReset(XMLPScanToken& token){ // Make sure this token is still legal if (!isLegalToken(token)) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Scan_BadPScanToken, fMemoryManager); // Reset the reader manager fReaderMgr.reset(); // And invalidate any tokens by bumping our sequence number fSequenceId++; // Reset our error count fErrorCount = 0;}void XMLScanner::setParseSettings(XMLScanner* const refScanner){ setDocHandler(refScanner->getDocHandler()); setDocTypeHandler(refScanner->getDocTypeHandler()); setErrorHandler(refScanner->getErrorHandler()); setErrorReporter(refScanner->getErrorReporter()); setEntityHandler(refScanner->getEntityHandler()); setDoNamespaces(refScanner->getDoNamespaces()); setDoSchema(refScanner->getDoSchema()); setCalculateSrcOfs(refScanner->getCalculateSrcOfs()); setStandardUriConformant(refScanner->getStandardUriConformant()); setExitOnFirstFatal(refScanner->getExitOnFirstFatal()); setValidationConstraintFatal(refScanner->getValidationConstraintFatal()); setIdentityConstraintChecking(refScanner->getIdentityConstraintChecking()); setValidationSchemaFullChecking(refScanner->getValidationSchemaFullChecking()); cacheGrammarFromParse(refScanner->isCachingGrammarFromParse()); useCachedGrammarInParse(refScanner->isUsingCachedGrammarInParse()); setLoadExternalDTD(refScanner->getLoadExternalDTD()); setNormalizeData(refScanner->getNormalizeData()); setExternalSchemaLocation(refScanner->getExternalSchemaLocation()); setExternalNoNamespaceSchemaLocation(refScanner->getExternalNoNamespaceSchemaLocation()); setValidationScheme(refScanner->getValidationScheme()); setSecurityManager(refScanner->getSecurityManager()); setPSVIHandler(refScanner->getPSVIHandler());}// ---------------------------------------------------------------------------// XMLScanner: Private helper methods.// ---------------------------------------------------------------------------// This method handles the common initialization, to avoid having to do// it redundantly in multiple constructors.void XMLScanner::commonInit(){ // We have to do a little init that involves statics, so we have to // use the mutex to protect it. { XMLMutexLock lockInit(&gScannerMutex()); // And assign ourselves the next available scanner id fScannerId = ++gScannerId; } // Create the attribute list, which is used to store attribute values // during start tag processing. Give it a reasonable initial size that // will serve for most folks, though it will grow as required. fAttrList = new (fMemoryManager) RefVectorOf<XMLAttr>(32, true, fMemoryManager); // Create the id ref list. This is used to enforce XML 1.0 ID ref // semantics, i.e. all id refs must refer to elements that exist fValidationContext = new (fMemoryManager) ValidationContextImpl(fMemoryManager); // Create the GrammarResolver //fGrammarResolver = new GrammarResolver(); // create initial, 64-element, fUIntPool fUIntPool = (unsigned int **)fMemoryManager->allocate(sizeof(unsigned int *) *fUIntPoolRowTotal); fUIntPool[0] = (unsigned int *)fMemoryManager->allocate(sizeof(unsigned int) << 6); memset(fUIntPool[0], 0, sizeof(unsigned int) << 6); fUIntPool[1] = 0; // Register self as handler for XMLBufferFull events on the CDATA buffer fCDataBuf.setFullHandler(this, fBufferSize);}void XMLScanner::initValidator(XMLValidator* theValidator) { // Tell the validator about the stuff it needs to know in order to // do its work. theValidator->setScannerInfo(this, &fReaderMgr, &fBufMgr); theValidator->setErrorReporter(fErrorReporter);}// ---------------------------------------------------------------------------// XMLScanner: Error emitting methods// ---------------------------------------------------------------------------// These methods are called whenever the scanner wants to emit an error.// It handles getting the message loaded, doing token replacement, etc...// and then calling the error handler, if its installed.bool XMLScanner::emitErrorWillThrowException(const XMLErrs::Codes toEmit){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?