igxmlscanner.cpp

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

CPP
1,855
字号
                    scanEndTag(gotData);                    break;                case Token_PI :                    scanPI();                    break;                case Token_StartTag :                    if (fDoNamespaces)                        scanStartTagNS(gotData);                    else                        scanStartTag(gotData);                    break;                default :                    fReaderMgr.skipToChar(chOpenAngle);                    break;            }            if (orgReader != fReaderMgr.getCurrentReaderNum())                emitError(XMLErrs::PartialMarkupInEntity);            // If we hit the end, then do the miscellaneous part            if (!gotData)            {                // Do post-parse validation if required                if (fValidate)                {                    //  We handle ID reference semantics at this level since                    //  its required by XML 1.0.                    checkIDRefs();                    // Then allow the validator to do any extra stuff it wants//                    fValidator->postParseValidation();                }                // That went ok, so scan for any miscellaneous stuff                scanMiscellaneous();                if (toCheckIdentityConstraint())                    fICHandler->endDocument();                if (fDocHandler)                    fDocHandler->endDocument();            }        }    }    //  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 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 user error            fReaderMgr.reset();            throw;        }        // Reset and return failure        fReaderMgr.reset();        return false;    }    catch(const OutOfMemoryException&)    {        throw;    }    catch(...)    {        // Reset and rethrow original error        fReaderMgr.reset();        throw;    }    // If we hit the end, then flush the reader manager    if (!retVal)        fReaderMgr.reset();    return retVal;}// ---------------------------------------------------------------------------//  IGXMLScanner: Private helper methods. Most of these are implemented in//  IGXMLScanner2.Cpp.// ---------------------------------------------------------------------------//  This method handles the common initialization, to avoid having to do//  it redundantly in multiple constructors.void IGXMLScanner::commonInit(){    //  Create the element state array    fElemState = (unsigned int*) fMemoryManager->allocate    (        fElemStateSize * sizeof(unsigned int)    ); //new unsigned int[fElemStateSize];    //  And we need one for the raw attribute scan. This just stores key/    //  value string pairs (prior to any processing.)    fRawAttrList = new (fMemoryManager) RefVectorOf<KVStringPair>(32, true, fMemoryManager);    //  Create the Validator and init them    fDTDValidator = new (fMemoryManager) DTDValidator();    initValidator(fDTDValidator);    fSchemaValidator = new (fMemoryManager) SchemaValidator(0, fMemoryManager);    initValidator(fSchemaValidator);    // Create IdentityConstraint info    fICHandler = new (fMemoryManager) IdentityConstraintHandler(this, fMemoryManager);    // Create schemaLocation pair info    fLocationPairs = new (fMemoryManager) ValueVectorOf<XMLCh*>(8, fMemoryManager);    // create pools for undeclared elements    fDTDElemNonDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(29, 128, fMemoryManager);    fSchemaElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);     fAttDefRegistry = new (fMemoryManager) RefHashTableOf<unsigned int>    (        131, false, new (fMemoryManager)HashPtr(), fMemoryManager    );    fUndeclaredAttrRegistry = new (fMemoryManager) RefHashTableOf<unsigned int>    (        7, false, new (fMemoryManager)HashXMLCh(), fMemoryManager    );    fUndeclaredAttrRegistryNS = new (fMemoryManager) RefHash2KeysTableOf<unsigned int>    (        7, false, new (fMemoryManager)HashXMLCh(), fMemoryManager    );    fPSVIAttrList = new (fMemoryManager) PSVIAttributeList(fMemoryManager);}void IGXMLScanner::cleanUp(){    fMemoryManager->deallocate(fElemState); //delete [] fElemState;    delete fRawAttrList;    delete fDTDValidator;    delete fSchemaValidator;    delete fICHandler;    delete fLocationPairs;    delete fDTDElemNonDeclPool;    delete fSchemaElemNonDeclPool;    delete fAttDefRegistry;    delete fUndeclaredAttrRegistry;    delete fUndeclaredAttrRegistryNS;    delete fPSVIAttrList;    delete fPSVIElement;    delete fErrorStack;}// ---------------------------------------------------------------------------//  IGXMLScanner: Private scanning methods// ---------------------------------------------------------------------------//  This method is called from scanStartTag() to handle the very raw initial//  scan of the attributes. It just fills in the passed collection with//  key/value pairs for each attribute. No processing is done on them at all.unsigned intIGXMLScanner::rawAttrScan(const   XMLCh* const                elemName                          ,       RefVectorOf<KVStringPair>&  toFill                          ,       bool&                       isEmpty){    //  Keep up with how many attributes we've seen so far, and how many    //  elements are available in the vector. This way we can reuse old    //  elements until we run out and then expand it.    unsigned int attCount = 0;    unsigned int curVecSize = toFill.size();    // Assume it is not empty    isEmpty = false;    //  We loop until we either see a /> or >, handling key/value pairs util    //  we get there. We place them in the passed vector, which we will expand    //  as required to hold them.    while (true)    {        // Get the next character, which should be non-space        XMLCh nextCh = fReaderMgr.peekNextChar();        //  If the next character is not a slash or closed angle bracket,        //  then it must be whitespace, since whitespace is required        //  between the end of the last attribute and the name of the next        //  one.        //        if (attCount)        {            if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))            {                if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))                {                    // Ok, skip by them and get another char                    fReaderMgr.getNextChar();                    fReaderMgr.skipPastSpaces();                    nextCh = fReaderMgr.peekNextChar();                }                 else                {                    // Emit the error but keep on going                    emitError(XMLErrs::ExpectedWhitespace);                }            }        }        //  Ok, here we first check for any of the special case characters.        //  If its not one, then we do the normal case processing, which        //  assumes that we've hit an attribute value, Otherwise, we do all        //  the special case checks.        if (!fReaderMgr.getCurrentReader()->isSpecialStartTagChar(nextCh))        {            //  Assume its going to be an attribute, so get a name from            //  the input.            if (!fReaderMgr.getName(fAttNameBuf))            {                emitError(XMLErrs::ExpectedAttrName);                fReaderMgr.skipPastChar(chCloseAngle);                return attCount;            }            // And next must be an equal sign            if (!scanEq())            {                static const XMLCh tmpList[] =                {                    chSingleQuote, chDoubleQuote, chCloseAngle                    , chOpenAngle, chForwardSlash, chNull                };                emitError(XMLErrs::ExpectedEqSign);                //  Try to sync back up by skipping forward until we either                //  hit something meaningful.                const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);                if ((chFound == chCloseAngle) || (chFound == chForwardSlash))                {                    // Jump back to top for normal processing of these                    continue;                }                else if ((chFound == chSingleQuote)                      ||  (chFound == chDoubleQuote)                      ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))                {                    // Just fall through assuming that the value is to follow                }                else if (chFound == chOpenAngle)                {                    // Assume a malformed tag and that new one is starting                    emitError(XMLErrs::UnterminatedStartTag, elemName);                    return attCount;                }                else                {                    // Something went really wrong                    return attCount;                }            }            //  Next should be the quoted attribute value. We just do a simple            //  and stupid scan of this value. The only thing we do here            //  is to expand entity references.            if (!basicAttrValueScan(fAttNameBuf.getRawBuffer(), fAttValueBuf))            {                static const XMLCh tmpList[] =                {                    chCloseAngle, chOpenAngle, chForwardSlash, chNull                };                emitError(XMLErrs::ExpectedAttrValue);                //  It failed, so lets try to get synced back up. We skip                //  forward until we find some whitespace or one of the                //  chars in our list.                const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);                if ((chFound == chCloseAngle)                ||  (chFound == chForwardSlash)                ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))                {                    //  Just fall through and process this attribute, though                    //  the value will be "".                }                else if (chFound == chOpenAngle)                {                    // Assume a malformed tag and that new one is starting                    emitError(XMLErrs::UnterminatedStartTag, elemName);                    return attCount;                }                else                {                    // Something went really wrong                    return attCount;                }            }            //  Make sure that the name is basically well formed for namespace            //  enabled rules. It either has no colons, or it has one which            //  is neither the first or last char.            const int colonFirst = XMLString::indexOf(fAttNameBuf.getRawBuffer(), chColon);            if (colonFirst != -1)            {                const int colonLast = XMLString::lastIndexOf(fAttNameBuf.getRawBuffer(), chColon);                if (colonFirst != colonLast)                {                    emitError(XMLErrs::TooManyColonsInName);                    continue;                }                else if ((colonFirst == 0)                      ||  (colonLast == (int)fAttNameBuf.getLen() - 1))                {                    emitError(XMLErrs::InvalidColonPos);                    continue;                }            }            //  And now lets add it to the passed collection. If we have not            //  filled it up yet, then we use the next element. Else we add            //  a new one.            KVStringPair* curPair = 0;            if (attCount >= curVecSize)            {                curPair = new (fMemoryManager) KVStringPair                (                    fAttNameBuf.getRawBuffer()                    , fAttValueBuf.getRawBuffer()                    , fMemoryManager

⌨️ 快捷键说明

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