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