using System; using System.Collections; using System.Globalization; using System.IO; using System.Text; namespace Mono.Xml { // Token: 0x020000EF RID: 239 internal class SmallXmlParser { // Token: 0x06000BE4 RID: 3044 RVA: 0x00035B24 File Offset: 0x00033D24 private Exception Error(string msg) { return new SmallXmlParserException(msg, this.line, this.column); } // Token: 0x06000BE5 RID: 3045 RVA: 0x00035B38 File Offset: 0x00033D38 private Exception UnexpectedEndError() { string[] array = new string[this.elementNames.Count]; this.elementNames.CopyTo(array, 0); return this.Error(string.Format("Unexpected end of stream. Element stack content is {0}", string.Join(",", array))); } // Token: 0x06000BE6 RID: 3046 RVA: 0x00035B80 File Offset: 0x00033D80 private bool IsNameChar(char c, bool start) { if (c == '-' || c == '.') { return !start; } if (c == ':' || c == '_') { return true; } if (c > 'Ā') { if (c == 'ۥ' || c == 'ۦ' || c == 'ՙ') { return true; } if ('ʻ' <= c && c <= 'ˁ') { return true; } } switch (char.GetUnicodeCategory(c)) { case UnicodeCategory.UppercaseLetter: case UnicodeCategory.LowercaseLetter: case UnicodeCategory.TitlecaseLetter: case UnicodeCategory.OtherLetter: case UnicodeCategory.LetterNumber: return true; case UnicodeCategory.ModifierLetter: case UnicodeCategory.NonSpacingMark: case UnicodeCategory.SpacingCombiningMark: case UnicodeCategory.EnclosingMark: case UnicodeCategory.DecimalDigitNumber: return !start; default: return false; } } // Token: 0x06000BE7 RID: 3047 RVA: 0x00035C4C File Offset: 0x00033E4C private bool IsWhitespace(int c) { switch (c) { case 9: case 10: case 13: break; default: if (c != 32) { return false; } break; } return true; } // Token: 0x06000BE8 RID: 3048 RVA: 0x00035C88 File Offset: 0x00033E88 public void SkipWhitespaces() { this.SkipWhitespaces(false); } // Token: 0x06000BE9 RID: 3049 RVA: 0x00035C94 File Offset: 0x00033E94 private void HandleWhitespaces() { while (this.IsWhitespace(this.Peek())) { this.buffer.Append((char)this.Read()); } if (this.Peek() != 60 && this.Peek() >= 0) { this.isWhitespace = false; } } // Token: 0x06000BEA RID: 3050 RVA: 0x00035CEC File Offset: 0x00033EEC public void SkipWhitespaces(bool expected) { for (;;) { int num = this.Peek(); switch (num) { case 9: case 10: case 13: break; default: if (num != 32) { goto Block_0; } break; } this.Read(); if (expected) { expected = false; } } Block_0: if (expected) { throw this.Error("Whitespace is expected."); } } // Token: 0x06000BEB RID: 3051 RVA: 0x00035D58 File Offset: 0x00033F58 private int Peek() { return this.reader.Peek(); } // Token: 0x06000BEC RID: 3052 RVA: 0x00035D68 File Offset: 0x00033F68 private int Read() { int num = this.reader.Read(); if (num == 10) { this.resetColumn = true; } if (this.resetColumn) { this.line++; this.resetColumn = false; this.column = 1; } else { this.column++; } return num; } // Token: 0x06000BED RID: 3053 RVA: 0x00035DCC File Offset: 0x00033FCC public void Expect(int c) { int num = this.Read(); if (num < 0) { throw this.UnexpectedEndError(); } if (num != c) { throw this.Error(string.Format("Expected '{0}' but got {1}", (char)c, (char)num)); } } // Token: 0x06000BEE RID: 3054 RVA: 0x00035E14 File Offset: 0x00034014 private string ReadUntil(char until, bool handleReferences) { while (this.Peek() >= 0) { char c = (char)this.Read(); if (c == until) { string text = this.buffer.ToString(); this.buffer.Length = 0; return text; } if (handleReferences && c == '&') { this.ReadReference(); } else { this.buffer.Append(c); } } throw this.UnexpectedEndError(); } // Token: 0x06000BEF RID: 3055 RVA: 0x00035E8C File Offset: 0x0003408C public string ReadName() { int num = 0; if (this.Peek() < 0 || !this.IsNameChar((char)this.Peek(), true)) { throw this.Error("XML name start character is expected."); } for (int i = this.Peek(); i >= 0; i = this.Peek()) { char c = (char)i; if (!this.IsNameChar(c, false)) { break; } if (num == this.nameBuffer.Length) { char[] array = new char[num * 2]; Array.Copy(this.nameBuffer, array, num); this.nameBuffer = array; } this.nameBuffer[num++] = c; this.Read(); } if (num == 0) { throw this.Error("Valid XML name is expected."); } return new string(this.nameBuffer, 0, num); } // Token: 0x06000BF0 RID: 3056 RVA: 0x00035F54 File Offset: 0x00034154 public void Parse(TextReader input, SmallXmlParser.IContentHandler handler) { this.reader = input; this.handler = handler; handler.OnStartParsing(this); while (this.Peek() >= 0) { this.ReadContent(); } this.HandleBufferedContent(); if (this.elementNames.Count > 0) { throw this.Error(string.Format("Insufficient close tag: {0}", this.elementNames.Peek())); } handler.OnEndParsing(this); this.Cleanup(); } // Token: 0x06000BF1 RID: 3057 RVA: 0x00035FD0 File Offset: 0x000341D0 private void Cleanup() { this.line = 1; this.column = 0; this.handler = null; this.reader = null; this.elementNames.Clear(); this.xmlSpaces.Clear(); this.attributes.Clear(); this.buffer.Length = 0; this.xmlSpace = null; this.isWhitespace = false; } // Token: 0x06000BF2 RID: 3058 RVA: 0x00036034 File Offset: 0x00034234 public void ReadContent() { if (this.IsWhitespace(this.Peek())) { if (this.buffer.Length == 0) { this.isWhitespace = true; } this.HandleWhitespaces(); } if (this.Peek() != 60) { this.ReadCharacters(); return; } this.Read(); int num = this.Peek(); if (num != 33) { if (num != 47) { string text; if (num != 63) { this.HandleBufferedContent(); text = this.ReadName(); while (this.Peek() != 62 && this.Peek() != 47) { this.ReadAttribute(this.attributes); } this.handler.OnStartElement(text, this.attributes); this.attributes.Clear(); this.SkipWhitespaces(); if (this.Peek() == 47) { this.Read(); this.handler.OnEndElement(text); } else { this.elementNames.Push(text); this.xmlSpaces.Push(this.xmlSpace); } this.Expect(62); return; } this.HandleBufferedContent(); this.Read(); text = this.ReadName(); this.SkipWhitespaces(); string text2 = string.Empty; if (this.Peek() != 63) { for (;;) { text2 += this.ReadUntil('?', false); if (this.Peek() == 62) { break; } text2 += "?"; } } this.handler.OnProcessingInstruction(text, text2); this.Expect(62); return; } else { this.HandleBufferedContent(); if (this.elementNames.Count == 0) { throw this.UnexpectedEndError(); } this.Read(); string text = this.ReadName(); this.SkipWhitespaces(); string text3 = (string)this.elementNames.Pop(); this.xmlSpaces.Pop(); if (this.xmlSpaces.Count > 0) { this.xmlSpace = (string)this.xmlSpaces.Peek(); } else { this.xmlSpace = null; } if (text != text3) { throw this.Error(string.Format("End tag mismatch: expected {0} but found {1}", text3, text)); } this.handler.OnEndElement(text); this.Expect(62); return; } } else { this.Read(); if (this.Peek() == 91) { this.Read(); if (this.ReadName() != "CDATA") { throw this.Error("Invalid declaration markup"); } this.Expect(91); this.ReadCDATASection(); return; } else { if (this.Peek() == 45) { this.ReadComment(); return; } if (this.ReadName() != "DOCTYPE") { throw this.Error("Invalid declaration markup."); } throw this.Error("This parser does not support document type."); } } } // Token: 0x06000BF3 RID: 3059 RVA: 0x0003630C File Offset: 0x0003450C private void HandleBufferedContent() { if (this.buffer.Length == 0) { return; } if (this.isWhitespace) { this.handler.OnIgnorableWhitespace(this.buffer.ToString()); } else { this.handler.OnChars(this.buffer.ToString()); } this.buffer.Length = 0; this.isWhitespace = false; } // Token: 0x06000BF4 RID: 3060 RVA: 0x0003637C File Offset: 0x0003457C private void ReadCharacters() { this.isWhitespace = false; for (;;) { int num = this.Peek(); int num2 = num; if (num2 == -1) { break; } if (num2 != 38) { if (num2 == 60) { return; } this.buffer.Append((char)this.Read()); } else { this.Read(); this.ReadReference(); } } } // Token: 0x06000BF5 RID: 3061 RVA: 0x000363E8 File Offset: 0x000345E8 private void ReadReference() { if (this.Peek() != 35) { string text = this.ReadName(); this.Expect(59); string text2 = text; switch (text2) { case "amp": this.buffer.Append('&'); return; case "quot": this.buffer.Append('"'); return; case "apos": this.buffer.Append('\''); return; case "lt": this.buffer.Append('<'); return; case "gt": this.buffer.Append('>'); return; } throw this.Error("General non-predefined entity reference is not supported in this parser."); } this.Read(); this.ReadCharacterReference(); } // Token: 0x06000BF6 RID: 3062 RVA: 0x0003651C File Offset: 0x0003471C private int ReadCharacterReference() { int num = 0; if (this.Peek() == 120) { this.Read(); for (int i = this.Peek(); i >= 0; i = this.Peek()) { if (48 <= i && i <= 57) { num <<= 4 + i - 48; } else if (65 <= i && i <= 70) { num <<= 4 + i - 65 + 10; } else { if (97 > i || i > 102) { break; } num <<= 4 + i - 97 + 10; } this.Read(); } } else { for (int j = this.Peek(); j >= 0; j = this.Peek()) { if (48 > j || j > 57) { break; } num <<= 4 + j - 48; this.Read(); } } return num; } // Token: 0x06000BF7 RID: 3063 RVA: 0x0003661C File Offset: 0x0003481C private void ReadAttribute(SmallXmlParser.AttrListImpl a) { this.SkipWhitespaces(true); if (this.Peek() == 47 || this.Peek() == 62) { return; } string text = this.ReadName(); this.SkipWhitespaces(); this.Expect(61); this.SkipWhitespaces(); int num = this.Read(); string text2; if (num != 34) { if (num != 39) { throw this.Error("Invalid attribute value markup."); } text2 = this.ReadUntil('\'', true); } else { text2 = this.ReadUntil('"', true); } if (text == "xml:space") { this.xmlSpace = text2; } a.Add(text, text2); } // Token: 0x06000BF8 RID: 3064 RVA: 0x000366CC File Offset: 0x000348CC private void ReadCDATASection() { int num = 0; while (this.Peek() >= 0) { char c = (char)this.Read(); if (c == ']') { num++; } else { if (c == '>' && num > 1) { for (int i = num; i > 2; i--) { this.buffer.Append(']'); } return; } for (int j = 0; j < num; j++) { this.buffer.Append(']'); } num = 0; this.buffer.Append(c); } } throw this.UnexpectedEndError(); } // Token: 0x06000BF9 RID: 3065 RVA: 0x00036770 File Offset: 0x00034970 private void ReadComment() { this.Expect(45); this.Expect(45); for (;;) { if (this.Read() == 45) { if (this.Read() == 45) { break; } } } if (this.Read() != 62) { throw this.Error("'--' is not allowed inside comment markup."); } } // Token: 0x04000342 RID: 834 private SmallXmlParser.IContentHandler handler; // Token: 0x04000343 RID: 835 private TextReader reader; // Token: 0x04000344 RID: 836 private Stack elementNames = new Stack(); // Token: 0x04000345 RID: 837 private Stack xmlSpaces = new Stack(); // Token: 0x04000346 RID: 838 private string xmlSpace; // Token: 0x04000347 RID: 839 private StringBuilder buffer = new StringBuilder(200); // Token: 0x04000348 RID: 840 private char[] nameBuffer = new char[30]; // Token: 0x04000349 RID: 841 private bool isWhitespace; // Token: 0x0400034A RID: 842 private SmallXmlParser.AttrListImpl attributes = new SmallXmlParser.AttrListImpl(); // Token: 0x0400034B RID: 843 private int line = 1; // Token: 0x0400034C RID: 844 private int column; // Token: 0x0400034D RID: 845 private bool resetColumn; // Token: 0x020000F0 RID: 240 public interface IContentHandler { // Token: 0x06000BFA RID: 3066 void OnStartParsing(SmallXmlParser parser); // Token: 0x06000BFB RID: 3067 void OnEndParsing(SmallXmlParser parser); // Token: 0x06000BFC RID: 3068 void OnStartElement(string name, SmallXmlParser.IAttrList attrs); // Token: 0x06000BFD RID: 3069 void OnEndElement(string name); // Token: 0x06000BFE RID: 3070 void OnProcessingInstruction(string name, string text); // Token: 0x06000BFF RID: 3071 void OnChars(string text); // Token: 0x06000C00 RID: 3072 void OnIgnorableWhitespace(string text); } // Token: 0x020000F1 RID: 241 public interface IAttrList { // Token: 0x170001B8 RID: 440 // (get) Token: 0x06000C01 RID: 3073 int Length { get; } // Token: 0x170001B9 RID: 441 // (get) Token: 0x06000C02 RID: 3074 bool IsEmpty { get; } // Token: 0x06000C03 RID: 3075 string GetName(int i); // Token: 0x06000C04 RID: 3076 string GetValue(int i); // Token: 0x06000C05 RID: 3077 string GetValue(string name); // Token: 0x170001BA RID: 442 // (get) Token: 0x06000C06 RID: 3078 string[] Names { get; } // Token: 0x170001BB RID: 443 // (get) Token: 0x06000C07 RID: 3079 string[] Values { get; } } // Token: 0x020000F2 RID: 242 private class AttrListImpl : SmallXmlParser.IAttrList { // Token: 0x170001BC RID: 444 // (get) Token: 0x06000C09 RID: 3081 RVA: 0x000367F4 File Offset: 0x000349F4 public int Length { get { return this.attrNames.Count; } } // Token: 0x170001BD RID: 445 // (get) Token: 0x06000C0A RID: 3082 RVA: 0x00036804 File Offset: 0x00034A04 public bool IsEmpty { get { return this.attrNames.Count == 0; } } // Token: 0x06000C0B RID: 3083 RVA: 0x00036814 File Offset: 0x00034A14 public string GetName(int i) { return (string)this.attrNames[i]; } // Token: 0x06000C0C RID: 3084 RVA: 0x00036828 File Offset: 0x00034A28 public string GetValue(int i) { return (string)this.attrValues[i]; } // Token: 0x06000C0D RID: 3085 RVA: 0x0003683C File Offset: 0x00034A3C public string GetValue(string name) { for (int i = 0; i < this.attrNames.Count; i++) { if ((string)this.attrNames[i] == name) { return (string)this.attrValues[i]; } } return null; } // Token: 0x170001BE RID: 446 // (get) Token: 0x06000C0E RID: 3086 RVA: 0x00036894 File Offset: 0x00034A94 public string[] Names { get { return (string[])this.attrNames.ToArray(typeof(string)); } } // Token: 0x170001BF RID: 447 // (get) Token: 0x06000C0F RID: 3087 RVA: 0x000368B0 File Offset: 0x00034AB0 public string[] Values { get { return (string[])this.attrValues.ToArray(typeof(string)); } } // Token: 0x06000C10 RID: 3088 RVA: 0x000368CC File Offset: 0x00034ACC internal void Clear() { this.attrNames.Clear(); this.attrValues.Clear(); } // Token: 0x06000C11 RID: 3089 RVA: 0x000368E4 File Offset: 0x00034AE4 internal void Add(string name, string value) { this.attrNames.Add(name); this.attrValues.Add(value); } // Token: 0x0400034F RID: 847 private ArrayList attrNames = new ArrayList(); // Token: 0x04000350 RID: 848 private ArrayList attrValues = new ArrayList(); } } }