Exemplo n.º 1
0
        /// <summary>
        /// Put bytes into the parser.
        /// </summary>
        /// <param name="buf">The bytes to put into the parse stream</param>
        /// <param name="offset">Offset into buf to start at</param>
        /// <param name="length">Number of bytes to write</param>
        public void Push(byte[] buf, int offset, int length)
        {
            // or assert, really, but this is a little nicer.
            if (length == 0)
                return;

            // No locking is required.  Read() won't get called again
            // until this method returns.

            // TODO: only do this copy if we have a partial token at the
            // end of parsing.
            byte[] copy = new byte[length];
            System.Buffer.BlockCopy(buf, offset, copy, 0, length);
            m_buf.Write(copy);

            byte[] b = m_buf.GetBuffer();
            int off = 0;
            TOK tok = TOK.END_TAG;
            ContentToken ct = new ContentToken();
            try
            {
                while (off < b.Length)
                {
                    if (m_cdata)
                        tok = m_enc.tokenizeCdataSection(b, off, b.Length, ct);
                    else
                        tok = m_enc.tokenizeContent(b, off, b.Length, ct);

                    switch (tok)
                    {
                        case TOK.EMPTY_ELEMENT_NO_ATTS:
                        case TOK.EMPTY_ELEMENT_WITH_ATTS:
                            StartTag(b, off, ct, tok);
                            EndTag(b, off, ct, tok);
                            break;
                        case TOK.START_TAG_NO_ATTS:
                        case TOK.START_TAG_WITH_ATTS:
                            StartTag(b, off, ct, tok);
                            break;
                        case TOK.END_TAG:
                            EndTag(b, off, ct, tok);
                            break;
                        case TOK.DATA_CHARS:
                        case TOK.DATA_NEWLINE:
                            AddText(utf.GetString(b, off, ct.TokenEnd - off));
                            break;
                        case TOK.CHAR_REF:
                        case TOK.MAGIC_ENTITY_REF:
                            AddText(new string(new char[] { ct.RefChar1 }));
                            break;
                        case TOK.CHAR_PAIR_REF:
                            AddText(new string(new char[] {ct.RefChar1,
                                                            ct.RefChar2}));
                            break;
                        case TOK.COMMENT:
                            if (current != null)
                            {
                                // <!-- 4
                                //  --> 3
                                int start = off + 4 * m_enc.MinBytesPerChar;
                                int end = ct.TokenEnd - off -
                                    7 * m_enc.MinBytesPerChar;
                                string text = utf.GetString(b, start, end);
                                current.AddChild(new Comment(text));
                            }
                            break;
                        case TOK.CDATA_SECT_OPEN:
                            m_cdata = true;
                            break;
                        case TOK.CDATA_SECT_CLOSE:
                            m_cdata = false;
                            break;
                        case TOK.XML_DECL:
                            // thou shalt use UTF8, and XML version 1.
                            // i shall ignore evidence to the contrary...

                            // TODO: Throw an exception if these assuptions are
                            // wrong
                            break;
                        case TOK.ENTITY_REF:
                        case TOK.PI:
            #if CF
                        throw new util.NotImplementedException("Token type not implemented: " + tok);
            #else
                        throw new System.NotImplementedException("Token type not implemented: " + tok);
            #endif
                    }
                    off = ct.TokenEnd;
                }
            }
            catch (PartialTokenException)
            {
                // ignored;
            }
            catch (ExtensibleTokenException)
            {
                // ignored;
            }
            catch (Exception ex)
            {
                if (OnStreamError != null)
                    OnStreamError(this, ex);
            }
            finally
            {
                m_buf.Clear(off);
            }
        }
Exemplo n.º 2
0
        private string NormalizeAttributeValue(byte[] buf, int offset, int length)
        {
            if (length == 0)
                return null;

            string val = null;
            BufferAggregate buffer = new BufferAggregate();
            byte[] copy = new byte[length];
            System.Buffer.BlockCopy(buf, offset, copy, 0, length);
            buffer.Write(copy);
            byte[] b = buffer.GetBuffer();
            int off = 0;
            TOK tok = TOK.END_TAG;
            ContentToken ct = new ContentToken();
            try
            {
                while (off < b.Length)
                {
                    //tok = m_enc.tokenizeContent(b, off, b.Length, ct);
                    tok = m_enc.tokenizeAttributeValue(b, off, b.Length, ct);

                    switch (tok)
                    {
                        case TOK.ATTRIBUTE_VALUE_S:
                        case TOK.DATA_CHARS:
                        case TOK.DATA_NEWLINE:
                            val += (utf.GetString(b, off, ct.TokenEnd - off));
                            break;
                        case TOK.CHAR_REF:
                        case TOK.MAGIC_ENTITY_REF:
                            val += new string(new char[] { ct.RefChar1 });
                            break;
                        case TOK.CHAR_PAIR_REF:
                            val += new string(new char[] {ct.RefChar1, ct.RefChar2});
                            break;
                        case TOK.ENTITY_REF:
            #if CF
                            throw new util.NotImplementedException("Token type not implemented: " + tok);
            #else
                            throw new System.NotImplementedException("Token type not implemented: " + tok);
            #endif
                    }
                    off = ct.TokenEnd;
                }
            }
            catch (PartialTokenException)
            {
                // ignored;
            }
            catch (ExtensibleTokenException)
            {
                // ignored;
            }
            catch (Exception ex)
            {
                if (OnStreamError != null)
                    OnStreamError(this, ex);
            }
            finally
            {
                buffer.Clear(off);
            }
            return val;
        }
Exemplo n.º 3
0
        private void StartTag(byte[] buf, int offset,
            ContentToken ct, TOK tok)
        {
            m_Depth++;
            int colon;
            string name;
            string prefix;
            Hashtable ht = new Hashtable();

            m_ns.PushScope();

            // if i have attributes
            if ((tok == TOK.START_TAG_WITH_ATTS) ||
                (tok == TOK.EMPTY_ELEMENT_WITH_ATTS))
            {
                int start;
                int end;
                string val;
                for (int i=0; i<ct.getAttributeSpecifiedCount(); i++)
                {
                    start =  ct.getAttributeNameStart(i);
                    end = ct.getAttributeNameEnd(i);
                    name = utf.GetString(buf, start, end - start);

                    start = ct.getAttributeValueStart(i);
                    end =  ct.getAttributeValueEnd(i);
                    //val = utf.GetString(buf, start, end - start);

                    val = NormalizeAttributeValue(buf, start, end - start);
                    // <foo b='&amp;'/>
                    // <foo b='&amp;amp;'
                    // TODO: if val includes &amp;, it gets double-escaped
                    if (name.StartsWith("xmlns:"))
                    {
                        colon = name.IndexOf(':');
                        prefix = name.Substring(colon+1);
                        m_ns.AddNamespace(prefix, val);
                    }
                    else if (name == "xmlns")
                    {
                        m_ns.AddNamespace(string.Empty, val);
                    }
                    else
                    {
                        ht.Add(name, val);
                    }
                }
            }

            name = utf.GetString(buf,
                offset + m_enc.MinBytesPerChar,
                ct.NameEnd - offset - m_enc.MinBytesPerChar);

            colon = name.IndexOf(':');
            string ns = "";
            prefix = null;
            if (colon > 0)
            {
                prefix = name.Substring(0, colon);
                name = name.Substring(colon + 1);
                ns = m_ns.LookupNamespace(prefix);
            }
            else
            {
                ns = m_ns.DefaultNamespace;
            }

            Element newel = ElementFactory.GetElement(prefix, name, ns);

            foreach (string attrname in ht.Keys)
            {
                newel.SetAttribute(attrname, (string)ht[attrname]);
            }

            if (m_root == null)
            {
                m_root = newel;
                //FireOnDocumentStart(m_root);
                if (OnStreamStart!=null)
                    OnStreamStart(this, m_root);
            }
            else
            {
                if (current != null)
                    current.AddChild(newel);
                current = newel;
            }
        }
Exemplo n.º 4
0
        private void EndTag(byte[] buf, int offset,	ContentToken ct, TOK tok)
        {
            m_Depth--;
            m_ns.PopScope();

            if (current == null)
            {// end of doc
                if (OnStreamEnd!=null)
                    OnStreamEnd(this, m_root);
            //				FireOnDocumentEnd();
                return;
            }

            string name = null;

            if ((tok == TOK.EMPTY_ELEMENT_WITH_ATTS) ||
                (tok == TOK.EMPTY_ELEMENT_NO_ATTS))
                name = utf.GetString(buf,
                    offset + m_enc.MinBytesPerChar,
                    ct.NameEnd - offset -
                    m_enc.MinBytesPerChar);
            else
                name = utf.GetString(buf,
                    offset + m_enc.MinBytesPerChar*2,
                    ct.NameEnd - offset -
                    m_enc.MinBytesPerChar*2);

            //			if (current.Name != name)
            //				throw new Exception("Invalid end tag: " + name +
            //					" != " + current.Name);

            Element parent = (Element) current.Parent;
            if (parent == null)
            {
                DoRaiseOnStreamElement(current);
                //if (OnStreamElement!=null)
                //    OnStreamElement(this, current);
                //FireOnElement(current);
            }
            current = parent;
        }