Example #1
0
       // parse tag
        private int ParseTag() {
            int LineNum = _Scanner.LineNum;
            int LinePos = _Scanner.LinePos;

            int token = _Scanner.ScanMarkup();

            switch (token) {
                case XmlToken.TAG:
                    _NextFunction = _ParseElementIndex;
                    _CantHaveXmlDecl = true;
                    _ContinueParsing = true;
                    break;
                case XmlToken.EOF:
                    return XmlToken.EOF;
                case XmlToken.PI:
                    {
                        LinePos += 2; //To Skip markup <?
                        if (_Scanner.IsToken("xml")) {
                            //
                            // if xml is declared, there should not be any token before this
                            // if it is from ResolveEntity(), xml decl is allowed and should
                            // not be returned
                            //
                            if (_CantHaveXmlDecl)
                                throw new XmlException(Res.Xml_XmlDeclNotFirst, LineNum, LinePos);
                            if (_PIToken == null)
                                _PIToken = new XmlNameValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.XmlDeclaration, -1, _Normalization);
                            _PIToken.LineNum = LineNum;
                            _PIToken.LinePos = LinePos;
                            ParseXmlDecl();

                            if (_IsExternal) {
                                _ContinueParsing = true;
                            }
                            else {
                                _PIToken.Name = _NameTable.Add("xml");
                                _PIToken.SetValue(_StringBuilder);
                                _PIToken.Depth = _ElementDepth + 1 + _EntityDepthOffset;
                                _CurrentToken = _PIToken;
                            }
                        }
                        else {
                            bool hasBody = _Scanner.ScanPIName();
                            String name = _Scanner.GetTextAtom();
                            if (String.Compare(name, "xml", true, CultureInfo.InvariantCulture) == 0)
                                throw new XmlException(Res.Xml_InvalidPIName, name, LineNum, LinePos);
                            if (_CheckNamespaces && _Scanner.Colon() != -1)
                                throw new XmlException(Res.Xml_InvalidPIName, name, LineNum, LinePos);
                            if (_PIToken == null)
                                _PIToken = new XmlNameValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.ProcessingInstruction,
                                                                        -1, _Normalization);
                            _CantHaveXmlDecl = true;
                            _PIToken.Name = name;
                            _PIToken.NodeType = XmlNodeType.ProcessingInstruction;
                            if (hasBody) {
                                _Scanner.ScanPI();
                                _PIToken.SetValue(_Scanner, null, _Scanner.StartPos, _Scanner.TextLength);
                            }
                            else {
                                _PIToken.Value = String.Empty;
                            }
                            _PIToken.Depth = _ElementDepth + 1 + _EntityDepthOffset;
                            _CurrentToken = _PIToken;
                            _Scanner.Advance(2);
                       }
                    }
                    break;

                case XmlToken.COMMENT:
                    LinePos += 4; //To Skip markup <!--
                    if (_CommentToken == null)
                        _CommentToken = new XmlValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.Comment, -1, _Normalization);
                    _CantHaveXmlDecl = true;
                    _CommentToken.SetValue(_Scanner, null, _Scanner.StartPos, _Scanner.TextLength);
                    _CommentToken.Depth = _ElementDepth + 1 + _EntityDepthOffset;
                    _CurrentToken = _CommentToken;
                    _Scanner.Advance(3);
                    break;

                case XmlToken.CDATA:
                    _CantHaveXmlDecl = true;
                    LinePos += 9; //To skip the Markup <![CDATA[
                    if ((XmlNodeType.Document == _PartialContentNodeType || XmlNodeType.None == _PartialContentNodeType)
                        && (_ElementStack.Length < 1 || _RootCount < 1))
                        throw new XmlException(Res.Xml_InvalidRootData, LineNum, LinePos);
                    if (_CDATAToken == null)
                        _CDATAToken = new XmlValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.CDATA, -1, _Normalization);
                    _CDATAToken.SetValue(_Scanner, null, _Scanner.StartPos, _Scanner.TextLength);
                    _CDATAToken.Depth = _ElementDepth + 1 + _EntityDepthOffset;
                    _CurrentToken = _CDATAToken;
                    _Scanner.Advance(3);
                    break;

                case XmlToken.DECL:
                    {

                        if (_DtdParser != null) {
                            //A document cant have multiple doctyp
                            throw new XmlException(Res.Xml_MultipleDTDsProvided, LineNum, LinePos);
                        }

                        if (_RootCount > 0) {
                            throw new XmlException(Res.Xml_BadDTDLocation, LineNum, LinePos);
                        }

                        int startPos = _Scanner.CurrentPos-2;
                        _Scanner.ReadBufferConsistency = _Scanner.StartPos;

                        if (_DocTypeToken == null)
                            _DocTypeToken = new XmlDtdTokenInfo(_Scanner, _NsMgr, XmlNodeType.DocumentType, -1, _Normalization);
                        _CantHaveXmlDecl = true;
                        _Used = -1;

                        _DocTypeToken.Name = ParseDtd( _Scanner );
                        if (_DtdParser != null) {
                            LinePos = _DtdParser.DTDNameStartPosition;
                            LineNum = _DtdParser.DTDNameStartLine;
                        }
                        if (!_BufferConsistency)
                            _Scanner.ReadBufferConsistency = -1;
                        _DocTypeToken._DtdParser = _DtdParser;
                        _DocTypeToken.Depth = _ElementDepth + 1 + _EntityDepthOffset;
                        _CurrentToken = _DocTypeToken;
                    }
                    break;

                case XmlToken.ENDTAG:
                    {
                        LinePos += 2; //to skip the markup </
                        _Scanner.ScanNameWOCharChecking();
                        if (_LastElementInfo == null) {
                            throw new XmlException(Res.Xml_UnexpectedEndTag, LineNum, LinePos);
                        }

                        int count = _Scanner.TextLength;
                        char[] scannerbuff = _Scanner.InternalBuffer;

                        if(_LastElementInfo._NameWPrefix.Length != count) {
                                // The length of the start tag and end tag should be the same.
                                // If it is not, no need to check char by char.
                                goto errorCase;
                        }
                        int scannerOffset = _Scanner.TextOffset;
                        for (int i = scannerOffset, j = 0; i < (scannerOffset + count)  && j < count; i++, j++) {
                            if (_LastElementInfo._NameWPrefix[j] != scannerbuff[i]) {
                                goto errorCase;

                            }
                        }

                        //
                        // begin and end tag has to come from the same scanner
                        //
                        if (_LastElementInfo._Scanner != _Scanner) {
                            throw new XmlException(Res.Xml_TagNotInTheSameEntity, _LastElementInfo._NameWPrefix, LineNum, LinePos);
                        }

                        _EndElementToken.SetName(_LastElementInfo._NameWPrefix, _LastElementInfo._LocalName, _LastElementInfo._Prefix, _LastElementInfo._NS,
                                              _ElementDepth + _EntityDepthOffset, _Scanner);
                        _CurrentEndElementStart = _Scanner.StartPos-2;
                        ReadEndElementToken();
                        _Scanner.ScanToken(XmlToken.TAGEND); // skip whitespace to the '>'
                        _CurrentEndElementEnd = _Scanner.CurrentPos;
                        _ElementDepth--;
                    }

                    break;

            }

            _CurrentToken.LineNum = LineNum;
            _CurrentToken.LinePos = LinePos;

            return token;
            errorCase:

            String[] args;
            string exceptionCode;
            if (String.Empty != _BaseURI) {
                args = new String[4];
                args[3] = _BaseURI;
                exceptionCode = Res.Xml_TagMismatchFileName;
            }
            else {
                args = new String[3];
                exceptionCode = Res.Xml_TagMismatch;
            }
            args[0] = _LastElementInfo._NameWPrefix;
            args[1] = _LastElementInfo._LineNumber.ToString();
            args[2] = _Scanner.GetText();
            throw new XmlException(exceptionCode, args, LineNum, LinePos);
        }
Example #2
0
       // protected constructor, users should not be using this
        /// <include file='doc\XmlTextReader.uex' path='docs/doc[@for="XmlTextReader.XmlTextReader1"]/*' />
        /// <internalonly/>
        /// <devdoc>
        ///    <para>Initializes a new instance of the XmlTextReader class with the specified XmlNameTable.</para>
        /// </devdoc>
        protected XmlTextReader( XmlNameTable nt ) {
            //
            // internal variables
            //
            _ElementDepth = -1;
            _EntityDepthOffset = 0;
            _ReadCount = -1;

            //
            // variables for properties
            //
            _ReadState = ReadState.Initial;
            _NextState = 1;

            //
            // create interal components
            //
            _NameTable = nt;
            _ElementStack = new HWStack(STACK_INCREMENT);
            _ScannerStack = new HWStack(STACK_INCREMENT);

            //
            //create atom
            //
            _StringName                 = _NameTable.Add("String");
            _MicrosoftSystemNamespace   = _NameTable.Add("System");
            _Decimal                    = _NameTable.Add("#decimal");
            _Hex                        = _NameTable.Add("#hexidecimal");
            _Amp                        = _NameTable.Add("amp");
            _Lt                         = _NameTable.Add("lt");
            _Gt                         = _NameTable.Add("gt");
            _Quot                       = _NameTable.Add("quot");
            _Apos                       = _NameTable.Add("apos");
            _XmlNs                      = _NameTable.Add("xmlns");
            _XmlSpaceAtom               = _NameTable.Add("xml:space");
            _XmlLangAtom                = _NameTable.Add("xml:lang");

            //
            //fields collection
            //
            _Used = -1;
            _MarkScannerCount = 10000;

            //
            _XmlSpace = XmlSpace.None;
            _XmlLang = String.Empty;
            _WhitespaceHandling = WhitespaceHandling.All;

            _XmlResolver = new XmlUrlResolver();
            _CheckNamespaces = true;

            _TmpToken  = new XmlNSElementTokenInfo(_Scanner, _NsMgr, XmlNodeType.None, String.Empty,-1, -1, -1, 0,false);
            _CurrentToken = _TmpToken;

            // PERF: these node types are not common therefore they
            // will only be constructed when used
            //
            _CommentToken = null;
            _CDATAToken = null;
            _DocTypeToken = null;
            _PIToken = null;
            _EndEntityToken = null;

            _NextFunction = _InitReader;

            _StringBuilder = new StringBuilder(100);
        }