using System;
using System.Collections;
-#if NET_2_0
using System.Collections.Generic;
-#endif
using System.Globalization;
using System.IO;
using System.Security.Permissions;
using System.Text;
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
- internal class XmlTextReader : XmlReader,
+ class XmlTextReader : XmlReader,
IXmlLineInfo, IXmlNamespaceResolver, IHasXmlParserContext
-#else
- [PermissionSet (SecurityAction.InheritanceDemand, Unrestricted = true)]
- public class XmlTextReader : XmlReader, IXmlLineInfo, IHasXmlParserContext
-#endif
{
#region Constructors
public XmlTextReader (string url, XmlNameTable nt)
{
- string uriString;
- Stream stream = GetStreamFromUrl (url, out uriString);
+ reader_uri = resolver.ResolveUri (null, url);
+ string uriString = (reader_uri == null) ? String.Empty : reader_uri.ToString ();
XmlParserContext ctx = new XmlParserContext (nt,
new XmlNamespaceManager (nt),
String.Empty,
XmlSpace.None);
- this.InitializeContext (uriString, ctx, new XmlStreamReader (stream), XmlNodeType.Document);
+ this.InitializeContext (uriString, ctx, null, XmlNodeType.Document);
}
public XmlTextReader (TextReader input, XmlNameTable nt)
internal XmlTextReader (bool dummy, XmlResolver resolver, string url, XmlNodeType fragType, XmlParserContext context)
{
if (resolver == null) {
-#if NET_2_1
+#if MOONLIGHT
resolver = new XmlXapResolver ();
#else
resolver = new XmlUrlResolver ();
}
this.XmlResolver = resolver;
string uriString;
+
Stream stream = GetStreamFromUrl (url, out uriString);
this.InitializeContext (uriString, context, new XmlStreamReader (stream), fragType);
}
InitializeContext (url, context, fragment, fragType);
}
- private Stream GetStreamFromUrl (string url, out string absoluteUriString)
+ Uri ResolveUri (string url)
+ {
+ return resolver.ResolveUri (null, url);
+ }
+
+ Stream GetStreamFromUrl (string url, out string absoluteUriString)
{
- Uri uri = resolver.ResolveUri (null, url);
+#if NET_2_1
+ if (url == null)
+ throw new ArgumentNullException ("url");
+ if (url.Length == 0)
+ throw new ArgumentException ("url");
+#endif
+ Uri uri = ResolveUri (url);
absoluteUriString = uri != null ? uri.ToString () : String.Empty;
return resolver.GetEntity (uri, null, typeof (Stream)) as Stream;
}
get { return parserContext.BaseURI; }
}
-#if NET_2_0
public override bool CanReadBinaryContent {
get { return true; }
}
public override bool CanReadValueChunk {
get { return true; }
}
-#else
- internal override bool CanReadBinaryContent {
- get { return true; }
- }
-
- internal override bool CanReadValueChunk {
- get { return true; }
- }
-#endif
internal bool CharacterChecking {
get { return checkCharacters; }
{
get { return parserContext.Encoding; }
}
-#if NET_2_0
+
public EntityHandling EntityHandling {
get { return entityHandling; }
set { entityHandling = value; }
}
-#endif
public override bool EOF {
get { return readState == ReadState.EndOfFile; }
get { return cursorToken.IsEmptyElement; }
}
-#if NET_2_0
-#else
- public override string this [int i] {
- get { return GetAttribute (i); }
- }
-
- public override string this [string name] {
- get { return GetAttribute (name); }
- }
-
- public override string this [string localName, string namespaceName] {
- get { return GetAttribute (localName, namespaceName); }
- }
-#endif
-
public int LineNumber {
get {
if (useProceedingLineInfo)
get { return readState; }
}
-#if NET_2_0
public override XmlReaderSettings Settings {
get { return base.Settings; }
}
-#endif
public override string Value {
get { return cursorToken.Value != null ? cursorToken.Value : String.Empty; }
private int GetIndexOfQualifiedAttribute (string localName, string namespaceURI)
{
+ namespaceURI = namespaceURI ?? String.Empty;
for (int i = 0; i < attributeCount; i++) {
XmlAttributeTokenInfo ti = attributeTokens [i];
if (ti.LocalName == localName && ti.NamespaceURI == namespaceURI)
return attributeTokens [idx].Value;
}
-#if NET_2_0
public IDictionary<string, string> GetNamespacesInScope (XmlNamespaceScope scope)
{
return nsmgr.GetNamespacesInScope (scope);
{
return GetNamespacesInScope (scope);
}
-#endif
public TextReader GetRemainder ()
{
return new StringReader (new string (peekChars, peekCharsIndex, peekCharsLength - peekCharsIndex) + reader.ReadToEnd ());
}
-#if NET_2_0
public bool HasLineInfo ()
-#else
- bool IXmlLineInfo.HasLineInfo ()
-#endif
{
return true;
}
return s == String.Empty ? null : s;
}
-#if NET_2_0
string IXmlNamespaceResolver.LookupPrefix (string ns)
{
return LookupPrefix (ns, false);
{
return nsmgr.LookupPrefix (ns, atomizedName);
}
-#endif
public override void MoveToAttribute (int i)
{
throw new InvalidOperationException ("XmlTextReader cannot resolve external entities.");
}
-#if NET_2_0
[MonoTODO] // FIXME: Implement, for performance improvement
public override void Skip ()
{
base.Skip ();
}
-#endif
#endregion
#region Internals
private StringBuilder valueBuffer;
+ Uri reader_uri;
private TextReader reader;
private char [] peekChars;
private int peekCharsIndex;
// These values are never re-initialized.
private bool namespaces = true;
private WhitespaceHandling whitespaceHandling = WhitespaceHandling.All;
-#if NET_2_1
+#if MOONLIGHT
private XmlResolver resolver = new XmlXapResolver ();
#else
private XmlResolver resolver = new XmlUrlResolver ();
#endif
checkCharacters = true;
-#if NET_2_0
if (Settings != null)
checkCharacters = Settings.CheckCharacters;
-#endif
prohibitDtd = false;
closeInput = true;
entityHandling = EntityHandling.ExpandCharEntities;
nsmgr = nsmgr != null ? nsmgr : new XmlNamespaceManager (nameTable);
if (url != null && url.Length > 0) {
+#if NET_2_1
+ Uri uri = new Uri (url, UriKind.RelativeOrAbsolute);
+#else
Uri uri = null;
try {
uri = new Uri (url, UriKind.RelativeOrAbsolute);
string path = Path.GetFullPath ("./a");
uri = new Uri (new Uri (path), url);
}
+#endif
parserContext.BaseURI = uri.ToString ();
}
}
}
-#if NET_2_0
internal ConformanceLevel Conformance {
get { return allowMultipleRoot ? ConformanceLevel.Fragment : ConformanceLevel.Document; }
set {
{
parserContext.NameTable = nameTable;
}
-#endif
// Use this method rather than setting the properties
// directly so that all the necessary properties can
private bool ReadTextReader (int remained)
{
+ if (reader == null && reader_uri != null) {
+ Uri uri = reader_uri;
+ reader_uri = null;
+ string uriString;
+ reader = new XmlStreamReader (GetStreamFromUrl (uri.ToString (), out uriString));
+ }
if (peekCharsLength < 0) { // initialized buffer
peekCharsLength = reader.Read (peekChars, 0, peekChars.Length);
return peekCharsLength > 0;
Uri buri =
BaseURI != String.Empty ?
new Uri (BaseURI) : null;
+ // xml:base="" without any base URI -> pointless. However there are
+ // some people who use such xml:base. Seealso bug #608391.
+ if (buri == null && String.IsNullOrEmpty (value))
+ break;
Uri uri = resolver.ResolveUri (
buri, value);
parserContext.BaseURI =
private void AppendValueChar (int ch)
{
- if (ch < Char.MaxValue)
+ if (ch <= Char.MaxValue)
valueBuffer.Append ((char) ch);
else
AppendSurrogatePairValueChar (ch);
break;
if (whitespacePool == null)
whitespacePool = new NameTable ();
-#if NET_2_0 && !NET_2_1
+#if !NET_2_1
valueBuffer.CopyTo (0, whitespaceCache, 0, len);
#else
for (int i = 0; i < len; i++)
// FIXME: it might be optimized by the JIT later,
// AppendValueChar (ch);
{
- if (ch < Char.MaxValue)
+ if (ch <= Char.MaxValue)
valueBuffer.Append ((char) ch);
else
AppendSurrogatePairValueChar (ch);
{
IncrementAttributeToken ();
XmlAttributeTokenInfo ati = attributeTokens [currentAttribute];
- ati.Name = parserContext.NameTable.Add (name);
+ ati.Name = NameTable.Add (name);
ati.Prefix = String.Empty;
ati.NamespaceURI = String.Empty;
IncrementAttributeValueToken ();
int predefined = XmlChar.GetPredefinedEntity (entName);
if (predefined < 0) {
CheckAttributeEntityReferenceWFC (entName);
-#if NET_2_0
if (entityHandling == EntityHandling.ExpandEntities) {
string value = DTD.GenerateEntityAttributeText (entName);
foreach (char c in (IEnumerable<char>) value)
AppendValueChar (c);
- } else
-#endif
- {
+ } else {
currentAttributeValueToken.ValueBufferEnd = valueBuffer.Length;
currentAttributeValueToken.NodeType = XmlNodeType.Text;
if (!isNewToken)
// FIXME: it might be optimized by the JIT later,
// AppendValueChar (ch);
{
- if (ch < Char.MaxValue)
+ if (ch <= Char.MaxValue)
valueBuffer.Append ((char) ch);
else
AppendSurrogatePairValueChar (ch);
}
// Encoding value should be checked inside XmlInputStream.
}
-#if NET_2_0
// this condition is to check if this instance is
// not created by XmlReader.Create() (which just
// omits strict text declaration check).
else if (Conformance == ConformanceLevel.Auto)
throw NotWFError ("Encoding declaration is mandatory in text declaration.");
-#endif
Expect ("?>");
// FIXME: it might be optimized by the JIT later,
// AppendValueChar (ch);
{
- if (ch < Char.MaxValue)
+ if (ch <= Char.MaxValue)
valueBuffer.Append ((char) ch);
else
AppendSurrogatePairValueChar (ch);
// AppendNameChar (ch);
{
// nameBuffer.Length is always non-0 so no need to ExpandNameCapacity () here
- if (ch < Char.MaxValue)
+ if (ch <= Char.MaxValue)
nameBuffer [nameLength++] = (char) ch;
else
AppendSurrogatePairNameChar (ch);
{
if (nameLength == nameCapacity)
ExpandNameCapacity ();
- if (ch < Char.MaxValue)
+ if (ch <= Char.MaxValue)
nameBuffer [nameLength++] = (char) ch;
else
AppendSurrogatePairNameChar (ch);
case -1:
throw NotWFError ("Unexpected end of xml.");
case '<':
- if (i + 1 == length)
- // if it does not end here,
- // it cannot store another
- // character, so stop here.
- return i;
Advance (c);
if (PeekChar () != '/') {
nestLevel++;
return i;
default:
Advance (c);
- if (c < Char.MaxValue)
+ if (c <= Char.MaxValue)
buffer [bufIndex++] = (char) c;
else {
buffer [bufIndex++] = (char) ((c - 0x10000) / 0x400 + 0xD800);