Exemplo n.º 1
0
        private void GotData(XmlParserResult data)
        {
            bool lStopReading = false;
            switch (data.Type)
            {
                case XmlParserResultType.Error:
                    SendStreamError(new StreamError { Error = ((XmlErrorResult)data).Error });
                    return;
                case XmlParserResultType.Node:
                    XmlNodeResult nd = (XmlNodeResult)data;
                    switch (nd.NodeType)
                    {
                        case XmlNodeType.XmlInfo: break; // who cares about that?
                        case XmlNodeType.Single:
                            if (fServerElementStack.Count == 0)
                            {
                                SendStreamError(new StreamError { Error = StreamErrorKind.InvalidXml });
                                return;
                            }
                            Element el = CreateNode(nd, fServerElementStack[fServerElementStack.Count - 1]);
                            if (this.fServerElementStack.Count <= 1)
                                lStopReading = GotFirstLevelElement(el);
                            break;
                        case XmlNodeType.Open:
                            el = CreateNode(nd, fServerElementStack.Count == 0 ? null : fServerElementStack[fServerElementStack.Count - 1]);
                            this.fServerElementStack.Add(el);
                            if (this.fServerElementStack.Count == 1)
                                GotRootLevelElement(el);

                            break;
                        case XmlNodeType.Close:
                            if (fServerElementStack.Count == 0 || !fServerElementStack[fServerElementStack.Count - 1].Matches(nd.Prefix, nd.Name))
                            {
                                SendStreamError(new StreamError { Error = StreamErrorKind.InvalidXml });
                                return;
                            }
                            el = fServerElementStack[fServerElementStack.Count - 1];
                            fServerElementStack.RemoveAt(fServerElementStack.Count - 1);
                            if (fServerElementStack.Count == 0)
                            {
                                Close();
                                break;
                            }
                            if (fServerElementStack.Count == 1)
                            {
                                lStopReading = GotFirstLevelElement(el);
                            }
                            break;
                    }
                    break;
                case XmlParserResultType.Text:
                    if (fServerElementStack.Count == 0)
                    {
                        // discard
                    }
                    else
                    {
                        fServerElementStack[fServerElementStack.Count - 1].Text += ((XmlTextResult)data).Text;
                    }
                    break;
            }
            if (!lStopReading)
                parser.ReadXmlElementAsync(new Action<XmlParserResult>(GotData), fServerElementStack.Count > 0);
        }
Exemplo n.º 2
0
        private void Read()
        {
            try
            {
                switch (state)
                {
                case AsyncState.AllowText:
                    state = AsyncState.GotAllowText;
                    if (BeginReadUntil(a => a == '<', true))
                    {
                        goto case AsyncState.GotAllowText;
                    }
                    return;

                case AsyncState.GotAllowText:
                    if (this.currentData.Length > 0)
                    {
                        state = AsyncState.None;
                        gotResultCallback(XmlParserResult.Create(UnEscape(Encoding.UTF8.GetString(this.currentData.GetBuffer(), 0, (int)currentData.Length))));
                        return;
                    }

                    goto case AsyncState.GotStartByte;

                case AsyncState.None:
                    state = AsyncState.GotStartByte;
                    if (BeginReadUntil(a => true, false))     // read until we've got something
                    {
                        goto case AsyncState.GotStartByte;
                    }
                    return;

                case AsyncState.GotStartByte:
                    if (ReadByte() != '<')
                    {
                        state = AsyncState.None;
                        gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                        return;
                    }
                    state = AsyncState.GotSecondByte;
                    if (BeginReadUntil(a => true, false))
                    {
                        goto case AsyncState.GotSecondByte;
                    }
                    return;

                case AsyncState.GotSecondByte:
                    currentData.SetLength(0);
                    int n = ReadByte();
                    switch (n)
                    {
                    case '?':
                        currentNodeType = XmlNodeType.XmlInfo;
                        break;

                    case '/':
                        currentNodeType = XmlNodeType.Close;
                        break;

                    default:
                        currentNodeType = XmlNodeType.Open;
                        if (ValidXmlNameChar((char)n, true))
                        {
                            currentData.WriteByte((byte)n);
                        }
                        else
                        {
                            state = AsyncState.None;
                            gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                            return;
                        }
                        break;
                    }
                    state = AsyncState.GotName;
                    if (BeginReadUntil(a => !ValidXmlNameChar((char)a, currentData.Length == 0), false))
                    {
                        goto case AsyncState.GotName;
                    }
                    return;

                case AsyncState.GotName:
                    name = Encoding.UTF8.GetString(this.currentData.GetBuffer(), 0, (int)currentData.Length);
                    attributes.Clear();
                    goto case AsyncState.SkipWhitespace;

                case AsyncState.SkipWhitespace:
                    state = AsyncState.AfterWhitespaceInElement;
                    if (BeginReadUntil(a => !(a == '\r' || a == '\n' || a == ' ' || a == '\t'), true))
                    {
                        goto case AsyncState.AfterWhitespaceInElement;
                    }
                    return;

                case AsyncState.AfterWhitespaceInElement:
                    n = ReadByte();
                    if (n == '/')
                    {
                        if (currentNodeType != XmlNodeType.Open)
                        {
                            state = AsyncState.None;
                            gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                            return;
                        }
                        currentNodeType = XmlNodeType.Single;
                        state           = AsyncState.WantClosingTag;
                        if (BeginReadUntil(a => true, false))
                        {
                            goto case AsyncState.WantClosingTag;
                        }
                        return;
                    }
                    else if (n == '?')
                    {
                        if (currentNodeType != XmlNodeType.XmlInfo)
                        {
                            state = AsyncState.None;
                            gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                            return;
                        }
                        state = AsyncState.WantClosingTag;
                        if (BeginReadUntil(a => true, false))
                        {
                            goto case AsyncState.WantClosingTag;
                        }
                        return;
                    }
                    else if (n == '>')
                    {
                        if (currentNodeType == XmlNodeType.XmlInfo)
                        {
                            state = AsyncState.None;
                            gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                            return;
                        }
                        state = AsyncState.None;
                        gotResultCallback(XmlParserResult.Create(currentNodeType, name, attributes));
                        return;
                    }
                    // attribute:
                    if (ValidXmlNameChar((char)n, true))
                    {
                        currentData.SetLength(0);
                        currentData.WriteByte((byte)n);
                        state = AsyncState.ReadAttributeName;
                        if (BeginReadUntil(a => !ValidXmlNameChar((char)a, false), false))
                        {
                            goto case AsyncState.ReadAttributeName;
                        }
                    }
                    else
                    {
                        state = AsyncState.None;
                        gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                    }
                    return;

                case AsyncState.WantClosingTag:
                    if (ReadByte() != '>')
                    {
                        state = AsyncState.None;
                        gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                        return;
                    }
                    state = AsyncState.None;
                    gotResultCallback(XmlParserResult.Create(currentNodeType, name, attributes));
                    return;

                case AsyncState.ReadAttributeName:
                    currattname = Encoding.UTF8.GetString(this.currentData.GetBuffer(), 0, (int)currentData.Length);
                    state       = AsyncState.AfterWhitespaceInAttributeBeforeEqual;
                    if (BeginReadUntil(a => !(a == '\r' || a == '\n' || a == ' ' || a == '\t'), true))
                    {
                        goto case AsyncState.AfterWhitespaceInAttributeBeforeEqual;
                    }
                    return;

                case AsyncState.AfterWhitespaceInAttributeBeforeEqual:
                    if (ReadByte() != '=')
                    {
                        state = AsyncState.None;
                        gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                        return;
                    }
                    state = AsyncState.AfterWhitespaceInAttributeAfterEqual;
                    if (BeginReadUntil(a => !(a == '\r' || a == '\n' || a == ' ' || a == '\t'), true))
                    {
                        goto case AsyncState.AfterWhitespaceInAttributeAfterEqual;
                    }
                    return;

                case AsyncState.AfterWhitespaceInAttributeAfterEqual:
                    n = ReadByte();
                    if (n == '"')
                    {
                        state = AsyncState.ReadStringDoubleQuote;
                        if (BeginReadUntil(a => a == '"', true))
                        {
                            goto case AsyncState.ReadStringDoubleQuote;
                        }
                    }
                    else if (n == '\'')
                    {
                        state = AsyncState.ReadStringSingleQuote;
                        if (BeginReadUntil(a => a == '\'', true))
                        {
                            goto case AsyncState.ReadStringSingleQuote;
                        }
                    }
                    else
                    {
                        state = AsyncState.None;
                        gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                    }
                    return;

                case AsyncState.ReadStringDoubleQuote:
                case AsyncState.ReadStringSingleQuote:
                    ReadByte();        // we don't do anything with this
                    attributes.Add(ParseAttribute(currattname, Encoding.UTF8.GetString(this.currentData.GetBuffer(), 0, (int)currentData.Length)));
                    goto case AsyncState.SkipWhitespace;

                default:
                    state = AsyncState.None;
                    gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));     // shouldn't happen
                    return;
                }
            }
            catch
            {
                state = AsyncState.None;
                gotResultCallback(XmlParserResult.Create(StreamErrorKind.InvalidXml));
                return;
            }
        }