Пример #1
0
 private void ReadAttribute(AttrListImpl a)
 {
     this.SkipWhitespaces(true);
     if ((this.Peek() != 0x2f) && (this.Peek() != 0x3e))
     {
         string str2;
         string name = this.ReadName();
         this.SkipWhitespaces();
         this.Expect(0x3d);
         this.SkipWhitespaces();
         int num = this.Read();
         if (num != 0x22)
         {
             if (num != 0x27)
             {
                 throw this.Error("Invalid attribute value markup.");
             }
             str2 = this.ReadUntil('\'', true);
         }
         else
         {
             str2 = this.ReadUntil('"', true);
         }
         if (name == "xml:space")
         {
             this.xmlSpace = str2;
         }
         a.Add(name, str2);
     }
 }
Пример #2
0
        private void ReadAttribute(AttrListImpl a)
        {
            SkipWhitespaces(true);
            if (Peek() == '/' || Peek() == '>')
            {
                // came here just to spend trailing whitespaces
                return;
            }

            string name = ReadName();
            string value;

            SkipWhitespaces();
            Expect('=');
            SkipWhitespaces();
            switch (Read())
            {
            case '\'':
                value = ReadUntil('\'', true);
                break;

            case '"':
                value = ReadUntil('"', true);
                break;

            default:
                throw Error("Invalid attribute value markup.");
            }
            if (name == "xml:space")
            {
                xmlSpace = value;
            }
            a.Add(name, value);
        }
Пример #3
0
        private void ReadAttribute(AttrListImpl a)
        {
            SkipWhitespaces(true);
            if (Peek() == '/' || Peek() == '>')
                // came here just to spend trailing whitespaces
                return;

            string name = ReadName();
            string value;
            SkipWhitespaces();
            Expect('=');
            SkipWhitespaces();
            switch (Read())
            {
                case '\'':
                    value = ReadUntil('\'', true);
                    break;
                case '"':
                    value = ReadUntil('"', true);
                    break;
                default:
                    throw Error("Invalid attribute value markup.");
            }
            if (name == "xml:space")
                xmlSpace = value;
            a.Add(name, value);
        }
Пример #4
0
        public void Parse(IReader reader, IHandler handler)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            if (handler == null)
            {
                handler = new HandlerAdapter();
            }
            AttrListImpl attrListImpl = new AttrListImpl();
            string       text         = null;
            Stack        stack        = new Stack();
            string       text2        = null;

            this.line = 1;
            this.col  = 0;
            int           num           = 0;
            int           num2          = 0;
            StringBuilder stringBuilder = new StringBuilder();
            bool          flag          = false;
            bool          flag2         = false;
            bool          flag3         = false;
            int           num3          = 0;

            handler.OnStartParsing(this);
            while (true)
            {
                this.col++;
                num = reader.Read();
                if (num == -1)
                {
                    break;
                }
                int num4 = "<>/?=&'\"![ ]\t\r\n".IndexOf((char)num) & 0xF;
                switch (num4)
                {
                case 13:
                    continue;

                case 12:
                    num4 = 10;
                    break;
                }
                if (num4 == 14)
                {
                    this.col = 0;
                    this.line++;
                    num4 = 10;
                }
                int num5 = Xlat(num4, num2);
                num2 = (num5 & 0xFF);
                if (num == 10 && (num2 == 14 || num2 == 15))
                {
                    continue;
                }
                num5 >>= 8;
                if (num2 >= 128)
                {
                    if (num2 == 255)
                    {
                        FatalErr("State dispatch error.");
                    }
                    else
                    {
                        FatalErr(errors[num2 ^ 0x80]);
                    }
                }
                switch (num5)
                {
                case 9:
                    break;

                case 0:
                    handler.OnStartElement(text2, attrListImpl);
                    if (num != 47)
                    {
                        stack.Push(text2);
                    }
                    else
                    {
                        handler.OnEndElement(text2);
                    }
                    attrListImpl.Clear();
                    break;

                case 1:
                {
                    text2         = stringBuilder.ToString();
                    stringBuilder = new StringBuilder();
                    string text6 = null;
                    if (stack.Count == 0 || text2 != (text6 = (stack.Pop() as string)))
                    {
                        if (text6 == null)
                        {
                            FatalErr("Tag stack underflow");
                        }
                        else
                        {
                            FatalErr($"Expected end tag '{text2}' but found '{text6}'");
                        }
                    }
                    handler.OnEndElement(text2);
                    break;
                }

                case 2:
                    text2         = stringBuilder.ToString();
                    stringBuilder = new StringBuilder();
                    if (num != 47 && num != 62)
                    {
                        break;
                    }
                    goto case 0;

                case 3:
                    text          = stringBuilder.ToString();
                    stringBuilder = new StringBuilder();
                    break;

                case 4:
                    if (text == null)
                    {
                        FatalErr("Internal error.");
                    }
                    attrListImpl.Add(text, stringBuilder.ToString());
                    stringBuilder = new StringBuilder();
                    text          = null;
                    break;

                case 5:
                    handler.OnChars(stringBuilder.ToString());
                    stringBuilder = new StringBuilder();
                    break;

                case 6:
                {
                    string text5 = "CDATA[";
                    flag2 = false;
                    flag3 = false;
                    switch (num)
                    {
                    case 45:
                        num = reader.Read();
                        if (num != 45)
                        {
                            FatalErr("Invalid comment");
                        }
                        this.col++;
                        flag2 = true;
                        this.twoCharBuff[0] = -1;
                        this.twoCharBuff[1] = -1;
                        break;

                    default:
                        flag3 = true;
                        num3  = 0;
                        break;

                    case 91:
                    {
                        for (int k = 0; k < text5.Length; k++)
                        {
                            if (reader.Read() != text5[k])
                            {
                                this.col += k + 1;
                                break;
                            }
                        }
                        this.col += text5.Length;
                        flag      = true;
                        break;
                    }
                    }
                    break;
                }

                case 7:
                {
                    int num20 = 0;
                    num = 93;
                    while (true)
                    {
                        switch (num)
                        {
                        case 93:
                            goto IL_0341;

                        default:
                        {
                            for (int j = 0; j < num20; j++)
                            {
                                stringBuilder.Append(']');
                            }
                            stringBuilder.Append((char)num);
                            num2 = 18;
                            break;
                        }

                        case 62:
                        {
                            for (int i = 0; i < num20 - 2; i++)
                            {
                                stringBuilder.Append(']');
                            }
                            flag = false;
                            break;
                        }
                        }
                        break;
IL_0341:
                        num = reader.Read();
                        num20++;
                    }
                    this.col += num20;
                    break;
                }

                case 8:
                    FatalErr($"Error {num2}");
                    break;

                case 10:
                    stringBuilder = new StringBuilder();
                    if (num == 60)
                    {
                        break;
                    }
                    goto case 11;

                case 11:
                    stringBuilder.Append((char)num);
                    break;

                case 12:
                    if (flag2)
                    {
                        if (num == 62 && this.twoCharBuff[0] == 45 && this.twoCharBuff[1] == 45)
                        {
                            flag2 = false;
                            num2  = 0;
                        }
                        else
                        {
                            this.twoCharBuff[0] = this.twoCharBuff[1];
                            this.twoCharBuff[1] = num;
                        }
                    }
                    else if (flag3)
                    {
                        if (num == 60 || num == 62)
                        {
                            num3 ^= 1;
                        }
                        if (num == 62 && num3 != 0)
                        {
                            flag3 = false;
                            num2  = 0;
                        }
                    }
                    else
                    {
                        if (this.splitCData && stringBuilder.Length > 0 && flag)
                        {
                            handler.OnChars(stringBuilder.ToString());
                            stringBuilder = new StringBuilder();
                        }
                        flag = false;
                        stringBuilder.Append((char)num);
                    }
                    break;

                case 13:
                {
                    num = reader.Read();
                    int num6 = this.col + 1;
                    if (num == 35)
                    {
                        int num7 = 10;
                        int num8 = 0;
                        int num9 = 0;
                        num = reader.Read();
                        num6++;
                        if (num == 120)
                        {
                            num = reader.Read();
                            num6++;
                            num7 = 16;
                        }
                        NumberStyles style = (num7 == 16) ? NumberStyles.HexNumber : NumberStyles.Integer;
                        while (true)
                        {
                            int num10 = -1;
                            if (char.IsNumber((char)num) || "abcdef".IndexOf(char.ToLower((char)num)) != -1)
                            {
                                try
                                {
                                    num10 = int.Parse(new string((char)num, 1), style);
                                }
                                catch (FormatException)
                                {
                                    num10 = -1;
                                }
                            }
                            if (num10 == -1)
                            {
                                break;
                            }
                            num8 *= num7;
                            num8 += num10;
                            num9++;
                            num = reader.Read();
                            num6++;
                        }
                        if (num == 59 && num9 > 0)
                        {
                            stringBuilder.Append((char)num8);
                        }
                        else
                        {
                            FatalErr("Bad char ref");
                        }
                    }
                    else
                    {
                        string text3  = "aglmopqstu";
                        string text4  = "&'\"><";
                        int    num11  = 0;
                        int    num12  = 15;
                        int    num13  = 0;
                        int    length = stringBuilder.Length;
                        while (true)
                        {
                            if (num11 != 15)
                            {
                                num11 = (text3.IndexOf((char)num) & 0xF);
                            }
                            if (num11 == 15)
                            {
                                FatalErr(errors[7]);
                            }
                            stringBuilder.Append((char)num);
                            int num14 = "U㾏侏ཟク\ue1f4⊙\ueeff\ueeffo"[num11];
                            int num15 = (num14 >> 4) & 0xF;
                            int num16 = num14 & 0xF;
                            int num17 = num14 >> 12;
                            int num18 = (num14 >> 8) & 0xF;
                            num = reader.Read();
                            num6++;
                            num11 = 15;
                            if (num15 != 15 && num == text3[num15])
                            {
                                if (num17 < 14)
                                {
                                    num12 = num17;
                                }
                                num13 = 12;
                            }
                            else if (num16 != 15 && num == text3[num16])
                            {
                                if (num18 < 14)
                                {
                                    num12 = num18;
                                }
                                num13 = 8;
                            }
                            else if (num == 59)
                            {
                                if (num12 != 15 && num13 != 0 && ((num14 >> num13) & 0xF) == 14)
                                {
                                    break;
                                }
                                continue;
                            }
                            num11 = 0;
                        }
                        int num19 = num6 - this.col - 1;
                        if (num19 > 0 && num19 < 5 && (StrEquals("amp", stringBuilder, length, num19) || StrEquals("apos", stringBuilder, length, num19) || StrEquals("quot", stringBuilder, length, num19) || StrEquals("lt", stringBuilder, length, num19) || StrEquals("gt", stringBuilder, length, num19)))
                        {
                            stringBuilder.Length = length;
                            stringBuilder.Append(text4[num12]);
                        }
                        else
                        {
                            FatalErr(errors[7]);
                        }
                    }
                    this.col = num6;
                    break;
                }

                default:
                    FatalErr($"Unexpected action code - {num5}.");
                    break;
                }
            }
            if (num2 != 0)
            {
                FatalErr("Unexpected EOF");
            }
            handler.OnEndParsing(this);
        }
Пример #5
0
		public void Parse(IReader reader, IHandler handler) {
			if (reader == null) throw new ArgumentNullException("reader");
			if (handler == null) handler = new HandlerAdapter();

			AttrListImpl attrList = new AttrListImpl();
			string lastAttrName = null;
			Stack tagStack = new Stack();
			string elementName = null;
			line = 1;
			col = 0;
			int currCh = 0;
			int stateCode = 0;
			StringBuilder sbChars = new StringBuilder();
			bool seenCData = false;
			bool isComment = false;
			bool isDTD = false;
			int bracketSwitch = 0;

			handler.OnStartParsing(this);

			while (true) {
				++this.col;

				currCh = reader.Read();

				if (currCh == -1) {
					if (stateCode != 0) {
						FatalErr("Unexpected EOF");
					}
					break;
				}

				int charCode = "<>/?=&'\"![ ]\t\r\n".IndexOf((char)currCh) & 0xF;
				if (charCode == (int)CharKind.CR) continue; // ignore
				// whitepace ::= (#x20 | #x9 | #xd | #xa)+
				if (charCode == (int)CharKind.TAB) charCode = (int)CharKind.SPACE; // tab == space
				if (charCode == (int)CharKind.EOL) {
					this.col = 0;
					this.line++;
					charCode = (int)CharKind.SPACE;
				}

				int actionCode = MiniParser.Xlat(charCode, stateCode);
				stateCode = actionCode & 0xFF;
				// Ignore newline inside attribute value.
				if (currCh == '\n' && (stateCode == 0xE || stateCode == 0xF)) continue;
				actionCode >>= 8;

				if (stateCode >= 0x80) {
					if (stateCode == 0xFF) {
						FatalErr("State dispatch error.");
					} else {
						FatalErr(errors[stateCode ^ 0x80]);
					}
				}

				switch (actionCode) {
				case (int)ActionCode.START_ELEM:
					handler.OnStartElement(elementName, attrList);
					if (currCh != '/') {
						tagStack.Push(elementName);
					} else {
						handler.OnEndElement(elementName);
					}
					attrList.Clear();
					break;

				case (int)ActionCode.END_ELEM:
					elementName = sbChars.ToString();
					sbChars = new StringBuilder();
					string endName = null;
					if (tagStack.Count == 0 ||
						elementName != (endName = tagStack.Pop() as string)) {
						if (endName == null) {
							FatalErr("Tag stack underflow");
						} else {
							FatalErr(String.Format("Expected end tag '{0}' but found '{1}'", elementName, endName));
						}
					}
					handler.OnEndElement(elementName);
					break;

				case (int)ActionCode.END_NAME:
					elementName = sbChars.ToString();
					sbChars = new StringBuilder();
					if (currCh != '/' && currCh != '>') break;
					goto case (int)ActionCode.START_ELEM;

				case (int)ActionCode.SET_ATTR_NAME:
					lastAttrName = sbChars.ToString();
					sbChars = new StringBuilder();
					break;

				case (int)ActionCode.SET_ATTR_VAL:
					if (lastAttrName == null) FatalErr("Internal error.");
					attrList.Add(lastAttrName, sbChars.ToString());
					sbChars = new StringBuilder();
					lastAttrName = null;
					break;

				case (int)ActionCode.SEND_CHARS:
					handler.OnChars(sbChars.ToString());
					sbChars = new StringBuilder();
					break;

				case (int)ActionCode.START_CDATA:
					string cdata = "CDATA[";
					isComment = false;
					isDTD = false;

					if (currCh == '-') {
						currCh = reader.Read();

						if (currCh != '-') FatalErr("Invalid comment");

						this.col++;
						isComment = true;
						twoCharBuff[0] = -1;
						twoCharBuff[1] = -1;
					} else {
						if (currCh != '[') {
							isDTD = true;
							bracketSwitch = 0;
							break;
						}

						for (int i = 0; i < cdata.Length; i++) {
							if (reader.Read() != cdata[i]) {
								this.col += i+1;
								break;
							}
						}
						this.col += cdata.Length;
						seenCData = true;
					}
					break;

				case (int)ActionCode.END_CDATA:
					int n = 0;
					currCh = ']';

					while (currCh == ']') {
						currCh = reader.Read();
						n++;
					}

					if (currCh != '>') {
						for (int i = 0; i < n; i++) sbChars.Append(']');
						sbChars.Append((char)currCh);
						stateCode = 0x12;
					} else {
						for (int i = 0; i < n-2; i++) sbChars.Append(']');
						seenCData = false;
					}

					this.col += n;
					break;

				case (int)ActionCode.ERROR:
					FatalErr(String.Format("Error {0}", stateCode));
					break;

				case (int)ActionCode.STATE_CHANGE:
					break;

				case (int)ActionCode.FLUSH_CHARS_STATE_CHANGE:
					sbChars = new StringBuilder();
					if (currCh != '<') goto case (int)ActionCode.ACC_CHARS_STATE_CHANGE;
					break;

				case (int)ActionCode.ACC_CHARS_STATE_CHANGE:
					sbChars.Append((char)currCh);
					break;

				case (int)ActionCode.ACC_CDATA:
					if (isComment) {
						if (currCh == '>'
							&& twoCharBuff[0] == '-'
							&& twoCharBuff[1] == '-') {
							isComment = false;
							stateCode = 0;
						} else {
							twoCharBuff[0] = twoCharBuff[1];
							twoCharBuff[1] = currCh;
						}
					} else if (isDTD) {
						if (currCh == '<' || currCh == '>') bracketSwitch ^= 1;
						if (currCh == '>' && bracketSwitch != 0) {
							isDTD = false;
							stateCode = 0;
						}
					} else {
						if (this.splitCData
							&& sbChars.Length > 0
							&& seenCData) {
							handler.OnChars(sbChars.ToString());
							sbChars = new StringBuilder();
						}
						seenCData = false;
						sbChars.Append((char)currCh);
					}
					break;

				case (int)ActionCode.PROC_CHAR_REF:
					currCh = reader.Read();
					int cl = this.col + 1;
					if (currCh == '#') {    // character reference
						int r = 10;
						int chCode = 0;
						int nDigits = 0;
						currCh = reader.Read();
						cl++;

						if (currCh == 'x') {
							currCh = reader.Read();
							cl++;
							r=16;
						}

						NumberStyles style = r == 16 ? NumberStyles.HexNumber : NumberStyles.Integer;

						while (true) {
							int x = -1;
							if (Char.IsNumber((char)currCh) || "abcdef".IndexOf(Char.ToLower((char)currCh)) != -1) {
								try {
									x = Int32.Parse(new string((char)currCh, 1), style);
								} catch (FormatException) {x = -1;}
							}
							if (x == -1) break;
							chCode *= r;
							chCode += x;
							nDigits++;
							currCh = reader.Read();
							cl++;
						}

						if (currCh == ';' && nDigits > 0) {
							sbChars.Append((char)chCode);
						} else {
							FatalErr("Bad char ref");
						}
					} else {
						// entity reference
						string entityRefChars = "aglmopqstu"; // amp | apos | quot | gt | lt
						string entities = "&'\"><";

						int pos = 0;
						int entIdx = 0xF;
						int predShift = 0;

						int sbLen = sbChars.Length;

						while (true) {
							if (pos != 0xF) pos = entityRefChars.IndexOf((char)currCh) & 0xF;
							if (pos == 0xF) FatalErr(errors[7]);
							sbChars.Append((char)currCh);

							int path = "\uFF35\u3F8F\u4F8F\u0F5F\uFF78\uE1F4\u2299\uEEFF\uEEFF\uFF4F"[pos];
							int lBr = (path >> 4) & 0xF;
							int rBr = path & 0xF;
							int lPred = path >> 12;
							int rPred = (path >> 8) & 0xF;
							currCh = reader.Read();
							cl++;
							pos = 0xF;
							if (lBr != 0xF && currCh == entityRefChars[lBr]) {
								if (lPred < 0xE) entIdx = lPred;
//								pred = lPred;
								predShift = 12; // left
							} else if (rBr != 0xF && currCh == entityRefChars[rBr]) {
								if (rPred < 0xE) entIdx = rPred;
//								pred = rPred;
								predShift = 8; // right
							} else if (currCh == ';') {
								if (entIdx != 0xF
									&& predShift != 0
									&& ((path >> predShift) & 0xF) == 0xE) break;
								continue; // pos == 0xF
							}

							pos=0;

						}

						int l = cl - this.col - 1;

						if ((l > 0 && l < 5)
							&&(StrEquals("amp", sbChars, sbLen, l)
							|| StrEquals("apos", sbChars, sbLen, l)
							|| StrEquals("quot", sbChars, sbLen, l)
							|| StrEquals("lt", sbChars, sbLen, l)
							|| StrEquals("gt", sbChars, sbLen, l))
							) {
							sbChars.Length = sbLen;
							sbChars.Append(entities[entIdx]);
						} else FatalErr(errors[7]);
					}

					this.col = cl;
					break;

				default:
					FatalErr(String.Format("Unexpected action code - {0}.", actionCode));
					break;
				}
			} // while (true)

			handler.OnEndParsing(this);

		} // Parse
Пример #6
0
        public void Parse(IReader reader, IHandler handler)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            if (handler == null)
            {
                handler = new HandlerAdapter();
            }

            var    attrList     = new AttrListImpl();
            string lastAttrName = null;
            var    tagStack     = new Stack();
            string elementName  = null;

            line = 1;
            col  = 0;
            int  currCh        = 0;
            int  stateCode     = 0;
            var  sbChars       = new StringBuilder();
            bool seenCData     = false;
            bool isComment     = false;
            bool isDTD         = false;
            int  bracketSwitch = 0;

            handler.OnStartParsing(this);

            while (true)
            {
                ++col;
                int prevCh = currCh;

                currCh = reader.Read();

                if (currCh == -1)
                {
                    if (stateCode != 0)
                    {
                        FatalErr("Unexpected EOF");
                    }
                    break;
                }

                int charCode = "<>/?=&'\"![ ]\t\r\n".IndexOf((char)currCh) & 0xF;
                if (charCode == (int)CharKind.CR)
                {
                    continue;                                // ignore
                }
                // whitepace ::= (#x20 | #x9 | #xd | #xa)+
                if (charCode == (int)CharKind.TAB)
                {
                    charCode = (int)CharKind.SPACE;                                  // tab == space
                }
                if (charCode == (int)CharKind.EOL)
                {
                    col = 0;
                    line++;
                    charCode = (int)CharKind.SPACE;
                }

                int actionCode = Xlat(charCode, stateCode);
                stateCode = actionCode & 0xFF;
                // Ignore newline inside attribute value.
                if (currCh == '\n' && (stateCode == 0xE || stateCode == 0xF))
                {
                    continue;
                }
                actionCode >>= 8;

                if (stateCode >= 0x80)
                {
                    if (stateCode == 0xFF)
                    {
                        FatalErr("State dispatch error.");
                    }
                    else
                    {
                        FatalErr(errors[stateCode ^ 0x80]);
                    }
                }

                switch (actionCode)
                {
                case (int)ActionCode.START_ELEM:
                    handler.OnStartElement(elementName, attrList);
                    if (currCh != '/')
                    {
                        tagStack.Push(elementName);
                    }
                    else
                    {
                        handler.OnEndElement(elementName);
                    }
                    attrList.Clear();
                    break;

                case (int)ActionCode.END_ELEM:
                    elementName = sbChars.ToString();
                    sbChars     = new StringBuilder();
                    string endName = null;
                    if (tagStack.Count == 0 ||
                        elementName != (endName = tagStack.Pop() as string))
                    {
                        if (endName == null)
                        {
                            FatalErr("Tag stack underflow");
                        }
                        else
                        {
                            FatalErr(String.Format("Expected end tag '{0}' but found '{1}'", elementName, endName));
                        }
                    }
                    handler.OnEndElement(elementName);
                    break;

                case (int)ActionCode.END_NAME:
                    elementName = sbChars.ToString();
                    sbChars     = new StringBuilder();
                    if (currCh != '/' && currCh != '>')
                    {
                        break;
                    }
                    goto case (int)ActionCode.START_ELEM;

                case (int)ActionCode.SET_ATTR_NAME:
                    lastAttrName = sbChars.ToString();
                    sbChars      = new StringBuilder();
                    break;

                case (int)ActionCode.SET_ATTR_VAL:
                    if (lastAttrName == null)
                    {
                        FatalErr("Internal error.");
                    }
                    attrList.Add(lastAttrName, sbChars.ToString());
                    sbChars      = new StringBuilder();
                    lastAttrName = null;
                    break;

                case (int)ActionCode.SEND_CHARS:
                    handler.OnChars(sbChars.ToString());
                    sbChars = new StringBuilder();
                    break;

                case (int)ActionCode.START_CDATA:
                    string cdata = "CDATA[";
                    isComment = false;
                    isDTD     = false;

                    if (currCh == '-')
                    {
                        currCh = reader.Read();

                        if (currCh != '-')
                        {
                            FatalErr("Invalid comment");
                        }

                        col++;
                        isComment      = true;
                        twoCharBuff[0] = -1;
                        twoCharBuff[1] = -1;
                    }
                    else
                    {
                        if (currCh != '[')
                        {
                            isDTD         = true;
                            bracketSwitch = 0;
                            break;
                        }

                        for (int i = 0; i < cdata.Length; i++)
                        {
                            if (reader.Read() != cdata[i])
                            {
                                col += i + 1;
                                break;
                            }
                        }
                        col      += cdata.Length;
                        seenCData = true;
                    }
                    break;

                case (int)ActionCode.END_CDATA:
                    int n = 0;
                    currCh = ']';

                    while (currCh == ']')
                    {
                        currCh = reader.Read();
                        n++;
                    }

                    if (currCh != '>')
                    {
                        for (int i = 0; i < n; i++)
                        {
                            sbChars.Append(']');
                        }
                        sbChars.Append((char)currCh);
                        stateCode = 0x12;
                    }
                    else
                    {
                        for (int i = 0; i < n - 2; i++)
                        {
                            sbChars.Append(']');
                        }
                        seenCData = false;
                    }

                    col += n;
                    break;

                case (int)ActionCode.ERROR:
                    FatalErr(String.Format("Error {0}", stateCode));
                    break;

                case (int)ActionCode.STATE_CHANGE:
                    break;

                case (int)ActionCode.FLUSH_CHARS_STATE_CHANGE:
                    sbChars = new StringBuilder();
                    if (currCh != '<')
                    {
                        goto case (int)ActionCode.ACC_CHARS_STATE_CHANGE;
                    }
                    break;

                case (int)ActionCode.ACC_CHARS_STATE_CHANGE:
                    sbChars.Append((char)currCh);
                    break;

                case (int)ActionCode.ACC_CDATA:
                    if (isComment)
                    {
                        if (currCh == '>' &&
                            twoCharBuff[0] == '-' &&
                            twoCharBuff[1] == '-')
                        {
                            isComment = false;
                            stateCode = 0;
                        }
                        else
                        {
                            twoCharBuff[0] = twoCharBuff[1];
                            twoCharBuff[1] = currCh;
                        }
                    }
                    else if (isDTD)
                    {
                        if (currCh == '<' || currCh == '>')
                        {
                            bracketSwitch ^= 1;
                        }
                        if (currCh == '>' && bracketSwitch != 0)
                        {
                            isDTD     = false;
                            stateCode = 0;
                        }
                    }
                    else
                    {
                        if (splitCData &&
                            sbChars.Length > 0 &&
                            seenCData)
                        {
                            handler.OnChars(sbChars.ToString());
                            sbChars = new StringBuilder();
                        }
                        seenCData = false;
                        sbChars.Append((char)currCh);
                    }
                    break;

                case (int)ActionCode.PROC_CHAR_REF:
                    currCh = reader.Read();
                    int cl = col + 1;
                    if (currCh == '#')
                    {
                        // character reference
                        int r       = 10;
                        int chCode  = 0;
                        int nDigits = 0;
                        currCh = reader.Read();
                        cl++;

                        if (currCh == 'x')
                        {
                            currCh = reader.Read();
                            cl++;
                            r = 16;
                        }

                        NumberStyles style = r == 16 ? NumberStyles.HexNumber : NumberStyles.Integer;

                        while (true)
                        {
                            int x = -1;
                            if (Char.IsNumber((char)currCh) || "abcdef".IndexOf(Char.ToLower((char)currCh)) != -1)
                            {
                                try
                                {
                                    x = Int32.Parse(new string((char)currCh, 1), style);
                                }
                                catch (FormatException)
                                {
                                    x = -1;
                                }
                            }
                            if (x == -1)
                            {
                                break;
                            }
                            chCode *= r;
                            chCode += x;
                            nDigits++;
                            currCh = reader.Read();
                            cl++;
                        }

                        if (currCh == ';' && nDigits > 0)
                        {
                            sbChars.Append((char)chCode);
                        }
                        else
                        {
                            FatalErr("Bad char ref");
                        }
                    }
                    else
                    {
                        // entity reference
                        string entityRefChars = "aglmopqstu";     // amp | apos | quot | gt | lt
                        string entities       = "&'\"><";

                        int pos       = 0;
                        int entIdx    = 0xF;
                        int pred      = 0;
                        int predShift = 0;

                        int sbLen = sbChars.Length;

                        while (true)
                        {
                            if (pos != 0xF)
                            {
                                pos = entityRefChars.IndexOf((char)currCh) & 0xF;
                            }
                            if (pos == 0xF)
                            {
                                FatalErr(errors[7]);
                            }
                            sbChars.Append((char)currCh);

                            int path  = "\uFF35\u3F8F\u4F8F\u0F5F\uFF78\uE1F4\u2299\uEEFF\uEEFF\uFF4F"[pos];
                            int lBr   = (path >> 4) & 0xF;
                            int rBr   = path & 0xF;
                            int lPred = path >> 12;
                            int rPred = (path >> 8) & 0xF;
                            currCh = reader.Read();
                            cl++;
                            pos = 0xF;
                            if (lBr != 0xF && currCh == entityRefChars[lBr])
                            {
                                if (lPred < 0xE)
                                {
                                    entIdx = lPred;
                                }
                                pred      = lPred;
                                predShift = 12;     // left
                            }
                            else if (rBr != 0xF && currCh == entityRefChars[rBr])
                            {
                                if (rPred < 0xE)
                                {
                                    entIdx = rPred;
                                }
                                pred      = rPred;
                                predShift = 8;     // right
                            }
                            else if (currCh == ';')
                            {
                                if (entIdx != 0xF &&
                                    predShift != 0 &&
                                    ((path >> predShift) & 0xF) == 0xE)
                                {
                                    break;
                                }
                                continue;     // pos == 0xF
                            }

                            pos = 0;
                        }

                        int l = cl - col - 1;

                        if ((l > 0 && l < 5) &&
                            (StrEquals("amp", sbChars, sbLen, l) ||
                             StrEquals("apos", sbChars, sbLen, l) ||
                             StrEquals("quot", sbChars, sbLen, l) ||
                             StrEquals("lt", sbChars, sbLen, l) ||
                             StrEquals("gt", sbChars, sbLen, l))
                            )
                        {
                            sbChars.Length = sbLen;
                            sbChars.Append(entities[entIdx]);
                        }
                        else
                        {
                            FatalErr(errors[7]);
                        }
                    }

                    col = cl;
                    break;

                default:
                    FatalErr(String.Format("Unexpected action code - {0}.", actionCode));
                    break;
                }
            } // while (true)

            handler.OnEndParsing(this);
        }
Пример #7
0
        public void Parse(IReader reader, IHandler handler)
        {
            int  num8;
            bool flag4;

            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            if (handler == null)
            {
                handler = new HandlerAdapter();
            }
            AttrListImpl attrs = new AttrListImpl();
            string       name  = null;
            Stack        stack = new Stack();
            string       str2  = null;

            this.line = 1;
            this.col  = 0;
            int           num   = 0;
            int           state = 0;
            StringBuilder sb    = new StringBuilder();
            bool          flag  = false;
            bool          flag2 = false;
            bool          flag3 = false;
            int           num3  = 0;

            handler.OnStartParsing(this);
            goto Label_0972;
Label_01ED:
            handler.OnStartElement(str2, attrs);
            if (num != 0x2f)
            {
                stack.Push(str2);
            }
            else
            {
                handler.OnEndElement(str2);
            }
            attrs.Clear();
            goto Label_0972;
Label_04F4:
            sb.Append((char)num);
            goto Label_0972;
Label_094D:
            this.col = num8;
Label_0972:
            flag4 = true;
            this.col++;
            num = reader.Read();
            if (num == -1)
            {
                if (state != 0)
                {
                    this.FatalErr("Unexpected EOF");
                }
                handler.OnEndParsing(this);
            }
            else
            {
                int charCode = "<>/?=&'\"![ ]\t\r\n".IndexOf((char)num) & 15;
                switch (charCode)
                {
                case 13:
                    goto Label_0972;

                case 12:
                    charCode = 10;
                    break;

                case 14:
                    this.col = 0;
                    this.line++;
                    charCode = 10;
                    break;
                }
                int num5 = Xlat(charCode, state);
                state = num5 & 0xff;
                if ((num != 10) || ((state != 14) && (state != 15)))
                {
                    int num6;
                    num5 = num5 >> 8;
                    if (state >= 0x80)
                    {
                        if (state == 0xff)
                        {
                            this.FatalErr("State dispatch error.");
                        }
                        else
                        {
                            this.FatalErr(errors[state ^ 0x80]);
                        }
                    }
                    switch (num5)
                    {
                    case 0:
                        goto Label_01ED;

                    case 1:
                    {
                        str2 = sb.ToString();
                        sb   = new StringBuilder();
                        string str3 = null;
                        if ((stack.Count == 0) || (str2 != (str3 = stack.Pop() as string)))
                        {
                            if (str3 != null)
                            {
                                this.FatalErr(string.Format("Expected end tag '{0}' but found '{1}'", str2, str3));
                            }
                            else
                            {
                                this.FatalErr("Tag stack underflow");
                            }
                        }
                        handler.OnEndElement(str2);
                        goto Label_0972;
                    }

                    case 2:
                        str2 = sb.ToString();
                        sb   = new StringBuilder();
                        switch (num)
                        {
                        case 0x2f:
                        case 0x3e:
                            goto Label_01ED;
                        }
                        goto Label_0972;

                    case 3:
                        name = sb.ToString();
                        sb   = new StringBuilder();
                        goto Label_0972;

                    case 4:
                        if (name == null)
                        {
                            this.FatalErr("Internal error.");
                        }
                        attrs.Add(name, sb.ToString());
                        sb   = new StringBuilder();
                        name = null;
                        goto Label_0972;

                    case 5:
                        handler.OnChars(sb.ToString());
                        sb = new StringBuilder();
                        goto Label_0972;

                    case 6:
                    {
                        string str4 = "CDATA[";
                        flag2 = false;
                        flag3 = false;
                        if (num != 0x2d)
                        {
                            if (num != 0x5b)
                            {
                                flag3 = true;
                                num3  = 0;
                            }
                            else
                            {
                                for (num6 = 0; num6 < str4.Length; num6++)
                                {
                                    if (reader.Read() != str4[num6])
                                    {
                                        this.col += num6 + 1;
                                        break;
                                    }
                                }
                                this.col += str4.Length;
                                flag      = true;
                            }
                        }
                        else
                        {
                            if (reader.Read() != 0x2d)
                            {
                                this.FatalErr("Invalid comment");
                            }
                            this.col++;
                            flag2 = true;
                            this.twoCharBuff[0] = -1;
                            this.twoCharBuff[1] = -1;
                        }
                        goto Label_0972;
                    }

                    case 7:
                    {
                        int num7 = 0;
                        num = 0x5d;
                        while (num == 0x5d)
                        {
                            num = reader.Read();
                            num7++;
                        }
                        if (num != 0x3e)
                        {
                            for (num6 = 0; num6 < num7; num6++)
                            {
                                sb.Append(']');
                            }
                            sb.Append((char)num);
                            state = 0x12;
                        }
                        else
                        {
                            for (num6 = 0; num6 < (num7 - 2); num6++)
                            {
                                sb.Append(']');
                            }
                            flag = false;
                        }
                        this.col += num7;
                        goto Label_0972;
                    }

                    case 8:
                        this.FatalErr(string.Format("Error {0}", state));
                        goto Label_0972;

                    case 9:
                        goto Label_0972;

                    case 10:
                        sb = new StringBuilder();
                        if (num == 60)
                        {
                            goto Label_0972;
                        }
                        goto Label_04F4;

                    case 11:
                        goto Label_04F4;

                    case 12:
                        if (flag2)
                        {
                            if (((num == 0x3e) && (this.twoCharBuff[0] == 0x2d)) && (this.twoCharBuff[1] == 0x2d))
                            {
                                flag2 = false;
                                state = 0;
                            }
                            else
                            {
                                this.twoCharBuff[0] = this.twoCharBuff[1];
                                this.twoCharBuff[1] = num;
                            }
                        }
                        else if (flag3)
                        {
                            switch (num)
                            {
                            case 60:
                            case 0x3e:
                                num3 ^= 1;
                                break;
                            }
                            if ((num == 0x3e) && (num3 != 0))
                            {
                                flag3 = false;
                                state = 0;
                            }
                        }
                        else
                        {
                            if ((this.splitCData && (sb.Length > 0)) && flag)
                            {
                                handler.OnChars(sb.ToString());
                                sb = new StringBuilder();
                            }
                            flag = false;
                            sb.Append((char)num);
                        }
                        goto Label_0972;

                    case 13:
                    {
                        num  = reader.Read();
                        num8 = this.col + 1;
                        if (num != 0x23)
                        {
                            string str5   = "aglmopqstu";
                            string str6   = "&'\"><";
                            int    num13  = 0;
                            int    num14  = 15;
                            int    num15  = 0;
                            int    length = sb.Length;
Label_0897:
                            flag4 = true;
                            if (num13 != 15)
                            {
                                num13 = str5.IndexOf((char)num) & 15;
                            }
                            if (num13 == 15)
                            {
                                this.FatalErr(errors[7]);
                            }
                            sb.Append((char)num);
                            int num17 = "U㾏侏ཟク⊙o"[num13];
                            int num18 = (num17 >> 4) & 15;
                            int num19 = num17 & 15;
                            int num20 = num17 >> 12;
                            int num21 = (num17 >> 8) & 15;
                            num = reader.Read();
                            num8++;
                            num13 = 15;
                            if ((num18 != 15) && (num == str5[num18]))
                            {
                                if (num20 < 14)
                                {
                                    num14 = num20;
                                }
                                num15 = 12;
                            }
                            else if ((num19 != 15) && (num == str5[num19]))
                            {
                                if (num21 < 14)
                                {
                                    num14 = num21;
                                }
                                num15 = 8;
                            }
                            else if (num == 0x3b)
                            {
                                if (((num14 != 15) && (num15 != 0)) && (((num17 >> num15) & 15) == 14))
                                {
                                    int len = (num8 - this.col) - 1;
                                    if (((len > 0) && (len < 5)) && (((StrEquals("amp", sb, length, len) || StrEquals("apos", sb, length, len)) || (StrEquals("quot", sb, length, len) || StrEquals("lt", sb, length, len))) || StrEquals("gt", sb, length, len)))
                                    {
                                        sb.Length = length;
                                        sb.Append(str6[num14]);
                                    }
                                    else
                                    {
                                        this.FatalErr(errors[7]);
                                    }
                                    goto Label_094D;
                                }
                                goto Label_0897;
                            }
                            num13 = 0;
                            goto Label_0897;
                        }
                        int num9  = 10;
                        int num10 = 0;
                        int num11 = 0;
                        num = reader.Read();
                        num8++;
                        if (num == 120)
                        {
                            num = reader.Read();
                            num8++;
                            num9 = 0x10;
                        }
                        NumberStyles style = (num9 == 0x10) ? NumberStyles.HexNumber : NumberStyles.Integer;
                        while (true)
                        {
                            flag4 = true;
                            int num12 = -1;
                            if (char.IsNumber((char)num) || ("abcdef".IndexOf(char.ToLower((char)num)) != -1))
                            {
                                try
                                {
                                    num12 = int.Parse(new string((char)num, 1), style);
                                }
                                catch (FormatException)
                                {
                                    num12 = -1;
                                }
                            }
                            if (num12 == -1)
                            {
                                if ((num == 0x3b) && (num11 > 0))
                                {
                                    sb.Append((char)num10);
                                }
                                else
                                {
                                    this.FatalErr("Bad char ref");
                                }
                                goto Label_094D;
                            }
                            num10 *= num9;
                            num10 += num12;
                            num11++;
                            num = reader.Read();
                            num8++;
                        }
                    }
                    }
                    this.FatalErr(string.Format("Unexpected action code - {0}.", num5));
                }
                goto Label_0972;
            }
        }