/// <summary> /// Called once an & character is being seen. /// </summary> /// <param name="c">The next character after the & character.</param> /// <returns>The entity token.</returns> String CharacterReference(Char c) { var start = _stringBuffer.Length; var hex = false; var numeric = c == Symbols.Num; if (numeric) { c = GetNext(); hex = c == 'x' || c == 'X'; if (hex) { c = GetNext(); while (c.IsHex()) { _stringBuffer.Append(c); c = GetNext(); } } else { while (c.IsDigit()) { _stringBuffer.Append(c); c = GetNext(); } } } else if (c.IsXmlNameStart()) { do { _stringBuffer.Append(c); c = GetNext(); } while (c.IsXmlName()); } if (c == Symbols.Semicolon && _stringBuffer.Length > start) { var length = _stringBuffer.Length - start; var content = _stringBuffer.ToString(start, length); _stringBuffer.Remove(start, length); if (numeric) { var number = numeric ? content.FromHex() : content.FromDec(); if (!number.IsValidAsCharRef()) throw XmlParseError.CharacterReferenceInvalidNumber.At(_position); return number.ConvertFromUtf32(); } else { var entity = _resolver.GetSymbol(content); if (String.IsNullOrEmpty(entity)) throw XmlParseError.CharacterReferenceInvalidCode.At(_position); return entity; } } throw XmlParseError.CharacterReferenceNotTerminated.At(GetCurrentPosition()); }
protected String EReference(Char c) { var buffer = Pool.NewStringBuilder(); if (c.IsXmlNameStart()) { do { buffer.Append(c); c = _stream.Next; } while (c.IsXmlName()); var temp = buffer.ToPool(); if (temp.Length > 0 && c == Specification.SC) { var p = _container.GetEntity(temp); if (p != null) return p.NodeValue; } } else if (c == Specification.NUM) { c = _src.Next; var hex = c == 'x' || c == 'X'; if (hex) c = _stream.Next; while (hex ? c.IsHex() : c.IsDigit()) { buffer.Append(c); c = _src.Next; } var temp = buffer.ToPool(); if (temp.Length > 0 && c == Specification.SC) { var num = hex ? temp.FromHex() : temp.FromDec(); if (num.IsValidAsCharRef()) return Char.ConvertFromUtf32(num); throw Errors.Xml(ErrorCode.CharacterReferenceInvalidNumber); } } throw Errors.Xml(ErrorCode.CharacterReferenceNotTerminated); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#sec-pi. /// </summary> /// <param name="c">The next input character.</param> /// <param name="pi">The processing instruction token.</param> XmlToken ProcessingTarget(Char c, XmlPIToken pi) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = GetNext(); } pi.Target = FlushBuffer(); if (pi.Target.Isi(TagNames.Xml)) throw XmlParseError.XmlInvalidPI.At(GetCurrentPosition()); if (c == Symbols.QuestionMark) { c = GetNext(); if (c == Symbols.GreaterThan) return pi; } else if (c.IsSpaceCharacter()) return ProcessingContent(GetNext(), pi); throw XmlParseError.XmlInvalidPI.At(GetCurrentPosition()); }
/// <summary> /// Called once an & character is being seen. /// </summary> /// <param name="c">The next character after the & character.</param> /// <returns>The entity token.</returns> XmlEntityToken CharacterReference(Char c) { if (c == Symbols.Num) { c = GetNext(); var isHex = c == 'x' || c == 'X'; if (isHex) { c = GetNext(); while (c.IsHex()) { _stringBuffer.Append(c); c = GetNext(); } } else { while (c.IsDigit()) { _stringBuffer.Append(c); c = GetNext(); } } if (_stringBuffer.Length > 0 && c == Symbols.Semicolon) return NewEntity(numeric: true, hex: isHex); } else if (c.IsXmlNameStart()) { do { _stringBuffer.Append(c); c = GetNext(); } while (c.IsXmlName()); if (c == Symbols.Semicolon) return NewEntity(); } throw XmlParseError.CharacterReferenceNotTerminated.At(GetCurrentPosition()); }
protected void PEReference(Char c, Boolean use = true) { var buffer = Pool.NewStringBuilder(); if (c.IsXmlNameStart()) { do { buffer.Append(c); c = _stream.Next; } while (c.IsXmlName()); var temp = buffer.ToPool(); if (c == Specification.SC) { var p = _container.GetParameter(temp); if (p != null) { if (use) { _stream.Push(temp, p.NodeValue); return; } else throw Errors.Xml(ErrorCode.DtdPEReferenceInvalid); } } } if (use) throw Errors.Xml(ErrorCode.DtdPEReferenceInvalid); _stringBuffer.Append(Specification.PERCENT).Append(buffer.ToString()); }
/// <summary> /// See 8.2.4.54 DOCTYPE name state /// </summary> /// <param name="c">The next input character.</param> /// <param name="doctype">The current doctype token.</param> /// <returns>The emitted token.</returns> XmlToken DoctypeName(Char c, XmlDoctypeToken doctype) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = GetNext(); } doctype.Name = FlushBuffer(); if (c == Symbols.GreaterThan) return doctype; else if (c.IsSpaceCharacter()) return DoctypeNameAfter(GetNext(), doctype); throw XmlParseError.DoctypeInvalid.At(GetCurrentPosition()); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Name. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> /// <returns>The emitted token.</returns> XmlToken TagName(Char c, XmlTagToken tag) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = _src.Next; } tag.Name = _stringBuffer.ToString(); if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); if (c == Specification.GT) return tag; else if (c.IsSpaceCharacter()) return AttributeBeforeName(_src.Next, tag); else if (c == Specification.SOLIDUS) return TagSelfClosing(_src.Next, tag); throw Errors.Xml(ErrorCode.XmlInvalidName); }
DtdToken EntityDeclarationAfter(Char c, DtdEntityToken decl) { if (c.IsSpaceCharacter()) { c = SkipSpaces(c); if (decl.IsExtern && !decl.IsParameter && String.IsNullOrEmpty(decl.ExternNotation) && _stream.ContinuesWith(NDATA)) { _stream.Advance(4); c = _stream.Next; while (c.IsSpaceCharacter()) c = _stream.Next; if (c.IsXmlNameStart()) { _stringBuffer.Clear(); do { _stringBuffer.Append(c); c = _stream.Next; } while (c.IsXmlName()); decl.ExternNotation = _stringBuffer.ToString(); return EntityDeclarationAfter(c, decl); } throw Errors.Xml(ErrorCode.DtdEntityInvalid); } } if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); else if (c == Specification.GT) return decl; throw Errors.Xml(ErrorCode.DtdEntityInvalid); }
AttributeDeclarationEntry AttributeDeclarationName(Char c) { var value = new AttributeDeclarationEntry(); do { _stringBuffer.Append(c); c = _stream.Next; } while (c.IsXmlName()); if (!c.IsSpaceCharacter()) throw Errors.Xml(ErrorCode.DtdAttListInvalid); value.Name = _stringBuffer.ToString(); _stringBuffer.Clear(); return AttributeDeclarationType(_stream.Next, value); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#sec-pi. /// </summary> /// <param name="c">The next input character.</param> /// <param name="pi">The processing instruction token.</param> DtdToken ProcessingTarget(Char c, DtdPIToken pi) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = _stream.Next; } pi.Target = _stringBuffer.ToString(); _stringBuffer.Clear(); if (String.Compare(pi.Target, Tags.XML, StringComparison.OrdinalIgnoreCase) == 0) return TextDecl(c); if (c == Specification.QM) { c = _stream.Next; if(c == Specification.GT) return pi; } else if (c.IsSpaceCharacter()) return ProcessingContent(_stream.Next, pi); throw Errors.Xml(ErrorCode.XmlInvalidPI); }
Boolean DeclarationName(Char c, DtdToken decl) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = _stream.Next; } if (c == Specification.PERCENT) { PEReference(_stream.Next); return DeclarationName(_stream.Current, decl); } decl.Name = _stringBuffer.ToString(); _stringBuffer.Clear(); if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); return c.IsSpaceCharacter(); }
/// <summary> /// See 8.2.4.54 DOCTYPE name state /// </summary> /// <param name="c">The next input character.</param> /// <param name="doctype">The current doctype token.</param> /// <returns>The emitted token.</returns> XmlToken DoctypeName(Char c, XmlDoctypeToken doctype) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = _src.Next; } doctype.Name = _stringBuffer.ToString(); _stringBuffer.Clear(); if (c == Specification.GT) return doctype; else if(c.IsSpaceCharacter()) return DoctypeNameAfter(_src.Next, doctype); throw Errors.Xml(ErrorCode.DoctypeInvalid); }
/// <summary> /// Called once an & character is being seen. /// </summary> /// <param name="c">The next character after the & character.</param> /// <returns>The entity token.</returns> XmlEntityToken CharacterReference(Char c) { var buffer = Pool.NewStringBuilder(); if (c == Specification.NUM) { c = _src.Next; var hex = c == 'x' || c == 'X'; if (hex) { c = _src.Next; while (c.IsHex()) { buffer.Append(c); c = _src.Next; } } else { while (c.IsDigit()) { buffer.Append(c); c = _src.Next; } } if (buffer.Length > 0 && c == Specification.SC) return new XmlEntityToken { Value = buffer.ToPool(), IsNumeric = true, IsHex = hex }; } else if (c.IsXmlNameStart()) { do { buffer.Append(c); c = _src.Next; } while (c.IsXmlName()); if (c == Specification.SC) return new XmlEntityToken { Value = buffer.ToPool() }; } buffer.ToPool(); throw Errors.Xml(ErrorCode.CharacterReferenceNotTerminated); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeName(Char c, XmlTagToken tag) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = _src.Next; } var name = _stringBuffer.ToString(); if(!String.IsNullOrEmpty(tag.GetAttribute(name))) throw Errors.Xml(ErrorCode.XmlUniqueAttribute); tag.AddAttribute(name); if (c.IsSpaceCharacter()) { do c = _src.Next; while (c.IsSpaceCharacter()); } if (c == Specification.EQ) return AttributeBeforeValue(_src.Next, tag); throw Errors.Xml(ErrorCode.XmlInvalidAttribute); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#dt-etag. /// </summary> /// <param name="c">The next input character.</param> XmlToken TagEnd(Char c) { if (c.IsXmlNameStart()) { do { _stringBuffer.Append(c); c = GetNext(); } while (c.IsXmlName()); while (c.IsSpaceCharacter()) c = GetNext(); if (c == Symbols.GreaterThan) { var tag = NewCloseTag(); tag.Name = FlushBuffer(); return tag; } } if (c == Symbols.EndOfFile) throw XmlParseError.EOF.At(GetCurrentPosition()); throw XmlParseError.XmlInvalidEndTag.At(GetCurrentPosition()); }
void AttributeDeclarationTypeEnumeration(Char c, AttributeEnumeratedType parent) { while (true) { while (c.IsSpaceCharacter()) c = _stream.Next; if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); if (!c.IsXmlName()) throw Errors.Xml(ErrorCode.DtdAttListInvalid); do { _stringBuffer.Append(c); c = _stream.Next; } while (c.IsXmlName()); while (c.IsSpaceCharacter()) c = _stream.Next; parent.Names.Add(_stringBuffer.ToString()); _stringBuffer.Clear(); if (c == Specification.RBC) break; else if (c == Specification.PIPE) c = _stream.Next; else throw Errors.Xml(ErrorCode.DtdAttListInvalid); } }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Name. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> /// <returns>The emitted token.</returns> XmlToken TagName(Char c, XmlTagToken tag) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = GetNext(); } tag.Name = FlushBuffer(); if (c == Symbols.EndOfFile) throw XmlParseError.EOF.At(GetCurrentPosition()); if (c == Symbols.GreaterThan) return tag; else if (c.IsSpaceCharacter()) return AttributeBeforeName(GetNext(), tag); else if (c == Symbols.Solidus) return TagSelfClosing(GetNext(), tag); throw XmlParseError.XmlInvalidName.At(GetCurrentPosition()); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#sec-pi. /// </summary> /// <param name="c">The next input character.</param> /// <param name="pi">The processing instruction token.</param> XmlToken ProcessingTarget(Char c, XmlPIToken pi) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = GetNext(); } pi.Target = FlushBuffer(); if (String.Compare(pi.Target, Tags.Xml, StringComparison.OrdinalIgnoreCase) == 0) throw XmlParseError.XmlInvalidPI.At(GetCurrentPosition()); if (c == Symbols.QuestionMark) { c = GetNext(); if (c == Symbols.GreaterThan) return pi; } else if (c.IsSpaceCharacter()) return ProcessingContent(GetNext(), pi); throw XmlParseError.XmlInvalidPI.At(GetCurrentPosition()); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#NT-Attribute. /// </summary> /// <param name="c">The next input character.</param> /// <param name="tag">The current tag token.</param> XmlToken AttributeName(Char c, XmlTagToken tag) { while (c.IsXmlName()) { _stringBuffer.Append(c); c = GetNext(); } var name = FlushBuffer(); if (!String.IsNullOrEmpty(tag.GetAttribute(name))) throw XmlParseError.XmlUniqueAttribute.At(GetCurrentPosition()); tag.AddAttribute(name); if (c.IsSpaceCharacter()) { do c = GetNext(); while (c.IsSpaceCharacter()); } if (c == Symbols.Equality) return AttributeBeforeValue(GetNext(), tag); throw XmlParseError.XmlInvalidAttribute.At(GetCurrentPosition()); }
/// <summary> /// More http://www.w3.org/TR/REC-xml/#dt-etag. /// </summary> /// <param name="c">The next input character.</param> XmlToken TagEnd(Char c) { if (c.IsXmlNameStart()) { _stringBuffer.Clear(); do { _stringBuffer.Append(c); c = _src.Next; } while (c.IsXmlName()); while (c.IsSpaceCharacter()) c = _src.Next; if (c == Specification.GT) { var tag = XmlToken.CloseTag(); tag.Name = _stringBuffer.ToString(); return tag; } } if (c == Specification.EOF) throw Errors.Xml(ErrorCode.EOF); throw Errors.Xml(ErrorCode.XmlInvalidEndTag); }