// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// FIXME:
-//
-// Some thought needs to be given to performance.
-//
-// If current node is on an Attribute, Prefix might be null, and
-// in several fields which uses XmlReader, it should be considered.
-//
-
using System;
using System.Collections;
using System.Globalization;
using System.Xml.Schema;
using Mono.Xml;
+#if NET_2_0
+using System.Xml;
+
+namespace Mono.Xml2
+#else
namespace System.Xml
+#endif
{
+
#if NET_2_0
- public class XmlTextReader : XmlReader,
+ internal class XmlTextReader : XmlReader,
IXmlLineInfo, IXmlNamespaceResolver, IHasXmlParserContext
#else
public class XmlTextReader : XmlReader, IXmlLineInfo, IHasXmlParserContext
get { return parserContext.BaseURI; }
}
-#if NET_2_0
- public override bool CanResolveEntity {
- get { return true; }
- }
-
-#endif
-
internal bool CharacterChecking {
get { return checkCharacters && normalization; }
set { checkCharacters = value; }
get { return parserContext.Encoding; }
}
#if NET_2_0
- [MonoTODO]
public EntityHandling EntityHandling {
get { return entityHandling; }
set { entityHandling = value; }
return ReadCharsInternal (buffer, offset, length);
}
-#if NET_2_0
- public override string ReadString ()
- {
- return ReadStringInternal ();
- }
-#elif NET_1_1
-#else
+#if NET_1_0
public override string ReadInnerXml ()
{
return ReadInnerXmlInternal ();
int predefined = XmlChar.GetPredefinedEntity (entName);
if (predefined < 0) {
CheckAttributeEntityReferenceWFC (entName);
- currentAttributeValueToken.ValueBufferEnd = valueLength;
- currentAttributeValueToken.NodeType = XmlNodeType.Text;
- if (!isNewToken)
- IncrementAttributeValueToken ();
- currentAttributeValueToken.Name = entName;
- currentAttributeValueToken.Value = String.Empty;
- currentAttributeValueToken.NodeType = XmlNodeType.EntityReference;
- incrementToken = true;
+#if NET_2_0
+ if (entityHandling == EntityHandling.ExpandEntities) {
+ string value = DTD.GenerateEntityAttributeText (entName);
+ foreach (char c in value)
+ AppendValueChar (c);
+ } else
+#endif
+ {
+ currentAttributeValueToken.ValueBufferEnd = valueLength;
+ currentAttributeValueToken.NodeType = XmlNodeType.Text;
+ if (!isNewToken)
+ IncrementAttributeValueToken ();
+ currentAttributeValueToken.Name = entName;
+ currentAttributeValueToken.Value = String.Empty;
+ currentAttributeValueToken.NodeType = XmlNodeType.EntityReference;
+ incrementToken = true;
+ }
}
else
AppendValueChar (predefined);
break;
default:
- // FIXME: this should be done by the JIT
if (CharacterChecking && XmlChar.IsInvalid (ch))
-// if (checkCharacters && normalization && XmlChar.IsInvalid (ch))
throw new XmlException (this, "Invalid character was found.");
// FIXME: it might be optimized by the JIT later,
// AppendValueChar (ch);
{
DTDEntityDeclaration entDecl =
DTD == null ? null : DTD.EntityDecls [entName];
- if (DTD != null && resolver != null && entDecl == null)
- throw new XmlException (this, "Referenced entity does not exist.");
-
- if (entDecl == null)
- return;
+ if (entDecl == null) {
+ if (entityHandling == EntityHandling.ExpandEntities
+ || (DTD != null && resolver != null && entDecl == null))
+ throw new XmlException (this,
+ String.Format ("Referenced entity '{0}' does not exist.", entName));
+ else
+ return;
+ }
if (entDecl.HasExternalReference)
throw new XmlException (this, "Reference to external entities is not allowed in the value of an attribute.");
--- /dev/null
+//\r
+// System.Xml.XmlTextReader2.cs - XmlTextReader for .NET 2.0\r
+//\r
+// Author:\r
+// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)\r
+//\r
+// Copyright (C) 2004 Novell, Inc.\r
+//\r
+\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+#if NET_2_0\r
+\r
+using XmlTextReaderImpl = Mono.Xml2.XmlTextReader;\r
+\r
+using System;\r
+using System.Collections;\r
+using System.Globalization;\r
+using System.IO;\r
+using System.Text;\r
+using System.Xml.Schema;\r
+using Mono.Xml;\r
+\r
+namespace System.Xml\r
+{\r
+ public class XmlTextReader : XmlReader,\r
+ IXmlLineInfo, IXmlNamespaceResolver, IHasXmlParserContext\r
+ {\r
+ XmlTextReader entity;\r
+ XmlTextReaderImpl source;\r
+ bool entityInsideAttribute;\r
+ bool insideAttribute;\r
+ string cachedAttributeValue;\r
+ bool attributeValueConsumed;\r
+\r
+ protected XmlTextReader ()\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (Stream input)\r
+ : this (new XmlStreamReader (input))\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (string url)\r
+ : this(url, new NameTable ())\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (TextReader input)\r
+ : this (input, new NameTable ())\r
+ {\r
+ }\r
+\r
+ protected XmlTextReader (XmlNameTable nt)\r
+ : this (String.Empty, XmlNodeType.Element, null)\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (Stream input, XmlNameTable nt)\r
+ : this(new XmlStreamReader (input), nt)\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (string url, Stream input)\r
+ : this (url, new XmlStreamReader (input))\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (string url, TextReader input)\r
+ : this (url, input, new NameTable ())\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (string url, XmlNameTable nt)\r
+ {\r
+ source = new XmlTextReaderImpl (url, nt);\r
+ }\r
+\r
+ public XmlTextReader (TextReader input, XmlNameTable nt)\r
+ : this (String.Empty, input, nt)\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (Stream xmlFragment, XmlNodeType fragType, XmlParserContext context)\r
+ {\r
+ source = new XmlTextReaderImpl (xmlFragment, fragType, context);\r
+ }\r
+\r
+ public XmlTextReader (string url, Stream input, XmlNameTable nt)\r
+ : this (url, new XmlStreamReader (input), nt)\r
+ {\r
+ }\r
+\r
+ public XmlTextReader (string url, TextReader input, XmlNameTable nt)\r
+ {\r
+ source = new XmlTextReaderImpl (url, input, nt);\r
+ }\r
+\r
+ public XmlTextReader (string xmlFragment, XmlNodeType fragType, XmlParserContext context)\r
+ {\r
+ source = new XmlTextReaderImpl (xmlFragment, fragType, context);\r
+ }\r
+\r
+ private XmlTextReader (XmlTextReaderImpl entityContainer, bool insideAttribute)\r
+ {\r
+ source = entityContainer;\r
+ this.entityInsideAttribute = insideAttribute;\r
+ }\r
+\r
+ #region Properties\r
+\r
+ private XmlReader Current {\r
+ get { return entity != null && entity.ReadState != ReadState.Initial ? (XmlReader) entity : source; }\r
+ }\r
+\r
+ public override int AttributeCount {\r
+ get { return Current.AttributeCount; }\r
+ }\r
+\r
+ public override string BaseURI {\r
+ get { return Current.BaseURI; }\r
+ }\r
+\r
+ public override bool CanResolveEntity {\r
+ get { return true; }\r
+ }\r
+ public override int Depth {\r
+ get {\r
+ // On EndEntity, depth is the same as that \r
+ // of EntityReference.\r
+ if (entity != null && entity.ReadState == ReadState.Interactive)\r
+ return source.Depth + entity.Depth + 1;\r
+ else\r
+ return source.Depth;\r
+ }\r
+ }\r
+\r
+ public override bool EOF {\r
+ get { return source.EOF; }\r
+ }\r
+\r
+ public override bool HasValue {\r
+ get { return Current.HasValue; }\r
+ }\r
+\r
+ public override bool IsDefault {\r
+ get { return Current.IsDefault; }\r
+ }\r
+\r
+ public override bool IsEmptyElement {\r
+ get { return Current.IsEmptyElement; }\r
+ }\r
+\r
+ public override string LocalName {\r
+ get { return Current.LocalName; }\r
+ }\r
+\r
+ public override string Name {\r
+ get { return Current.Name; }\r
+ }\r
+\r
+ public override string NamespaceURI {\r
+ get { return Current.NamespaceURI; }\r
+ }\r
+\r
+ public override XmlNameTable NameTable {\r
+ get { return Current.NameTable; }\r
+ }\r
+\r
+ public override XmlNodeType NodeType {\r
+ get {\r
+ if (Current == entity)\r
+ return entity.EOF ? XmlNodeType.EndEntity : entity.NodeType;\r
+ else\r
+ return source.NodeType;\r
+ }\r
+ }\r
+\r
+ internal XmlParserContext ParserContext {\r
+ get { return ((IHasXmlParserContext) Current).ParserContext; }\r
+ }\r
+\r
+ XmlParserContext IHasXmlParserContext.ParserContext {\r
+ get { return this.ParserContext; }\r
+ }\r
+\r
+ public override string Prefix {\r
+ get { return Current.Prefix; }\r
+ }\r
+\r
+ public override char QuoteChar {\r
+ get { return Current.QuoteChar; }\r
+ }\r
+\r
+ public override ReadState ReadState {\r
+ get { return entity != null ? ReadState.Interactive : source.ReadState; }\r
+ }\r
+\r
+ public override XmlReaderSettings Settings {\r
+ get { return Current.Settings; }\r
+ }\r
+\r
+ public override string Value {\r
+ get { return Current.Value; }\r
+ }\r
+\r
+ public override string XmlLang {\r
+ get { return Current.XmlLang; }\r
+ }\r
+\r
+ public override XmlSpace XmlSpace {\r
+ get { return Current.XmlSpace; }\r
+ }\r
+\r
+ // non-overrides\r
+\r
+ internal bool CharacterChecking {\r
+ get {\r
+ if (entity != null)\r
+ return entity.CharacterChecking;\r
+ else\r
+ return source.CharacterChecking;\r
+ }\r
+ set {\r
+ if (entity != null)\r
+ entity.CharacterChecking = value;\r
+ source.CharacterChecking = value;\r
+ }\r
+ }\r
+\r
+ internal bool CloseInput {\r
+ get {\r
+ if (entity != null)\r
+ return entity.CloseInput;\r
+ else\r
+ return source.CloseInput;\r
+ }\r
+ set {\r
+ if (entity != null)\r
+ entity.CloseInput = value;\r
+ source.CloseInput = value;\r
+ }\r
+ }\r
+\r
+ internal ConformanceLevel Conformance {\r
+ set {\r
+ if (entity != null)\r
+ entity.Conformance = value;\r
+ source.Conformance = value;\r
+ }\r
+ }\r
+\r
+ internal XmlResolver Resolver {\r
+ get { return source.Resolver; }\r
+ }\r
+\r
+ private void CopyProperties (XmlTextReader other)\r
+ {\r
+ CharacterChecking = other.CharacterChecking;\r
+ CloseInput = other.CloseInput;\r
+ if (other.Settings != null)\r
+ Conformance = other.Settings.ConformanceLevel;\r
+ XmlResolver = other.Resolver;\r
+ }\r
+\r
+ // public members\r
+\r
+ public Encoding Encoding {\r
+ get {\r
+ if (entity != null)\r
+ return entity.Encoding;\r
+ else\r
+ return source.Encoding;\r
+ }\r
+ }\r
+\r
+ public EntityHandling EntityHandling {\r
+ get { return source.EntityHandling; }\r
+ set {\r
+ if (entity != null)\r
+ entity.EntityHandling = value;\r
+ source.EntityHandling = value;\r
+ }\r
+ }\r
+\r
+ public int LineNumber {\r
+ get {\r
+ if (entity != null)\r
+ return entity.LineNumber;\r
+ else\r
+ return source.LineNumber;\r
+ }\r
+ }\r
+\r
+ public int LinePosition {\r
+ get {\r
+ if (entity != null)\r
+ return entity.LinePosition;\r
+ else\r
+ return source.LinePosition;\r
+ }\r
+ }\r
+\r
+ public bool Namespaces {\r
+ get { return source.Namespaces; }\r
+ set {\r
+ if (entity != null)\r
+ entity.Namespaces = value;\r
+ source.Namespaces = value;\r
+ }\r
+ }\r
+\r
+ public bool Normalization {\r
+ get { return source.Normalization; }\r
+ set {\r
+ if (entity != null)\r
+ entity.Normalization = value;\r
+ source.Normalization = value;\r
+ }\r
+ }\r
+\r
+ public bool ProhibitDtd {\r
+ get { return source.ProhibitDtd; }\r
+ set {\r
+ if (entity != null)\r
+ entity.ProhibitDtd = value;\r
+ source.ProhibitDtd = value;\r
+ }\r
+ }\r
+\r
+ public WhitespaceHandling WhitespaceHandling {\r
+ get { return source.WhitespaceHandling; }\r
+ set {\r
+ if (entity != null)\r
+ entity.WhitespaceHandling = value;\r
+ source.WhitespaceHandling = value;\r
+ }\r
+ }\r
+\r
+ public XmlResolver XmlResolver {\r
+ set {\r
+ if (entity != null)\r
+ entity.XmlResolver = value;\r
+ source.XmlResolver = value;\r
+ }\r
+ }\r
+\r
+ #endregion\r
+\r
+ #region Methods\r
+\r
+ internal void AdjustLineInfoOffset (int lineNumberOffset, int linePositionOffset)\r
+ {\r
+ if (entity != null)\r
+ entity.AdjustLineInfoOffset (lineNumberOffset, linePositionOffset);\r
+ source.AdjustLineInfoOffset (lineNumberOffset, linePositionOffset);\r
+ }\r
+\r
+ internal void SetNameTable (XmlNameTable nameTable)\r
+ {\r
+ if (entity != null)\r
+ entity.SetNameTable (nameTable);\r
+ source.SetNameTable (nameTable);\r
+ }\r
+\r
+ // overrides\r
+\r
+ public override void Close ()\r
+ {\r
+ if (entity != null)\r
+ entity.Close ();\r
+ source.Close ();\r
+ }\r
+\r
+ public override string GetAttribute (int i)\r
+ {\r
+ return Current.GetAttribute (i);\r
+ }\r
+\r
+ // MS.NET 1.0 msdn says that this method returns String.Empty\r
+ // for absent attribute, but in fact it returns null.\r
+ // This description is corrected in MS.NET 1.1 msdn.\r
+ public override string GetAttribute (string name)\r
+ {\r
+ return Current.GetAttribute (name);\r
+ }\r
+\r
+ public override string GetAttribute (string localName, string namespaceURI)\r
+ {\r
+ return Current.GetAttribute (localName, namespaceURI);\r
+ }\r
+\r
+ public IDictionary GetNamespacesInScope (XmlNamespaceScope scope)\r
+ {\r
+ return ((IXmlNamespaceResolver) Current).GetNamespacesInScope (scope);\r
+ }\r
+\r
+ public override string LookupNamespace (string prefix)\r
+ {\r
+ return Current.LookupNamespace (prefix, false);\r
+ }\r
+\r
+ public override string LookupNamespace (string prefix, bool atomizedName)\r
+ {\r
+ return ((IXmlNamespaceResolver) Current).LookupNamespace (prefix, atomizedName);\r
+ }\r
+\r
+ string IXmlNamespaceResolver.LookupPrefix (string ns)\r
+ {\r
+ return ((IXmlNamespaceResolver) Current).LookupPrefix (ns, false);\r
+ }\r
+\r
+ public string LookupPrefix (string ns, bool atomizedName)\r
+ {\r
+ return ((IXmlNamespaceResolver) Current).LookupPrefix (ns, atomizedName);\r
+ }\r
+\r
+ public override void MoveToAttribute (int i)\r
+ {\r
+ if (entity != null && entityInsideAttribute) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ Current.MoveToAttribute (i);\r
+ insideAttribute = true;\r
+ }\r
+\r
+ public override bool MoveToAttribute (string name)\r
+ {\r
+ if (entity != null && !entityInsideAttribute)\r
+ return entity.MoveToAttribute (name);\r
+ if (!source.MoveToAttribute (name))\r
+ return false;\r
+ if (entity != null && entityInsideAttribute) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ insideAttribute = true;\r
+ return true;\r
+ }\r
+\r
+ public override bool MoveToAttribute (string localName, string namespaceName)\r
+ {\r
+ if (entity != null && !entityInsideAttribute)\r
+ return entity.MoveToAttribute (localName, namespaceName);\r
+ if (!source.MoveToAttribute (localName, namespaceName))\r
+ return false;\r
+ if (entity != null && entityInsideAttribute) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ insideAttribute = true;\r
+ return true;\r
+ }\r
+\r
+ public override bool MoveToElement ()\r
+ {\r
+ if (entity != null && entityInsideAttribute) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ if (!Current.MoveToElement ())\r
+ return false;\r
+ insideAttribute = false;\r
+ return true;\r
+ }\r
+\r
+ public override bool MoveToFirstAttribute ()\r
+ {\r
+ if (entity != null && !entityInsideAttribute)\r
+ return entity.MoveToFirstAttribute ();\r
+ if (!source.MoveToFirstAttribute ())\r
+ return false;\r
+ if (entity != null && entityInsideAttribute) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ insideAttribute = true;\r
+ return true;\r
+ }\r
+\r
+ public override bool MoveToNextAttribute ()\r
+ {\r
+ if (entity != null && !entityInsideAttribute)\r
+ return entity.MoveToNextAttribute ();\r
+ if (!source.MoveToNextAttribute ())\r
+ return false;\r
+ if (entity != null && entityInsideAttribute) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ insideAttribute = true;\r
+ return true;\r
+ }\r
+\r
+ public override bool Read ()\r
+ {\r
+ insideAttribute = false;\r
+\r
+ if (entity != null && (entityInsideAttribute || entity.EOF)) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ if (entity != null) {\r
+ if (entity.Read ())\r
+ return true;\r
+ if (EntityHandling == EntityHandling.ExpandEntities) {\r
+ // EndEntity must be skipped\r
+ entity.Close ();\r
+ entity = null;\r
+ return Read ();\r
+ }\r
+ else\r
+ return true; // either success or EndEntity\r
+ }\r
+ else {\r
+ if (!source.Read ())\r
+ return false;\r
+ if (EntityHandling == EntityHandling.ExpandEntities\r
+ && source.NodeType == XmlNodeType.EntityReference) {\r
+ ResolveEntity ();\r
+ return Read ();\r
+ }\r
+ return true;\r
+ }\r
+ }\r
+\r
+ public override bool ReadAttributeValue ()\r
+ {\r
+ if (entity != null && entityInsideAttribute) {\r
+ if (entity.EOF) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ else {\r
+ entity.Read ();\r
+ return true; // either success or EndEntity\r
+ }\r
+ }\r
+ return Current.ReadAttributeValue ();\r
+ }\r
+\r
+ public override string ReadString ()\r
+ {\r
+ return base.ReadString ();\r
+ }\r
+\r
+ public void ResetState ()\r
+ {\r
+ if (entity != null)\r
+ entity.ResetState ();\r
+ source.ResetState ();\r
+ }\r
+\r
+ public override void ResolveEntity ()\r
+ {\r
+ if (entity != null)\r
+ entity.ResolveEntity ();\r
+ else {\r
+ if (source.NodeType != XmlNodeType.EntityReference)\r
+ throw new InvalidOperationException ("The current node is not an Entity Reference");\r
+ XmlTextReaderImpl entReader = \r
+ ParserContext.Dtd.GenerateEntityContentReader (source.Name, ParserContext);\r
+ if (entReader == null)\r
+ throw new XmlException (this as IXmlLineInfo, String.Format ("Reference to undeclared entity '{0}'.", source.Name));\r
+ entity = new XmlTextReader (\r
+ entReader, insideAttribute);\r
+ entity.CopyProperties (this);\r
+ }\r
+ }\r
+\r
+ public override void Skip ()\r
+ {\r
+ base.Skip ();\r
+ }\r
+\r
+ [MonoTODO ("Check how expanded entity is handled here.")]\r
+ public TextReader GetRemainder ()\r
+ {\r
+ if (entity != null) {\r
+ entity.Close ();\r
+ entity = null;\r
+ }\r
+ return source.GetRemainder ();\r
+ }\r
+\r
+ public bool HasLineInfo ()\r
+ {\r
+ return true;\r
+ }\r
+\r
+ [MonoTODO ("Check how expanded entity is handled here.")]\r
+ public int ReadBase64 (byte [] buffer, int offset, int length)\r
+ {\r
+ if (entity != null)\r
+ return entity.ReadBase64 (buffer, offset, length);\r
+ else\r
+ return source.ReadBase64 (buffer, offset, length);\r
+ }\r
+\r
+ [MonoTODO ("Check how expanded entity is handled here.")]\r
+ public int ReadBinHex (byte [] buffer, int offset, int length)\r
+ {\r
+ if (entity != null)\r
+ return entity.ReadBinHex (buffer, offset, length);\r
+ else\r
+ return source.ReadBinHex (buffer, offset, length);\r
+ }\r
+\r
+ [MonoTODO ("Check how expanded entity is handled here.")]\r
+ public int ReadChars (char [] buffer, int offset, int length)\r
+ {\r
+ if (entity != null)\r
+ return entity.ReadChars (buffer, offset, length);\r
+ else\r
+ return source.ReadChars (buffer, offset, length);\r
+ }\r
+\r
+ #endregion\r
+ }\r
+}\r
+\r
+#endif\r