Selaa lähdekoodia

2005-12-09 Atsushi Enomoto <[email protected]>

	* XmlChar.cs : removed incorrect comment.
	* XmlReader.cs : Create() clones XmlReaderSettings (if supplied).
	  For wrapped XmlReader, check ConformanceLevel to be consistent.
	* XmlTextReader.cs, XmlTextReader2.cs : added get_Conformance for
	  internal use. Removed unused fields.
	* XmlInputStream.cs : updated NonBlockingStreamReader to the latest
	  StreamReader (it is almost a copy).

	* XmlReaderSettingsTests.cs : added some ConformanceLevel tests.
	  Added CreateClonesSettings() to make sure XmlReader.Create() clones
	  XmlReaderSettings.


svn path=/trunk/mcs/; revision=54151
Atsushi Eno 20 vuotta sitten
vanhempi
sitoutus
de3ddcb8ca

+ 10 - 0
mcs/class/System.XML/System.Xml/ChangeLog

@@ -1,3 +1,13 @@
+2005-12-09  Atsushi Enomoto <[email protected]>
+
+	* XmlChar.cs : removed incorrect comment.
+	* XmlReader.cs : Create() clones XmlReaderSettings (if supplied).
+	  For wrapped XmlReader, check ConformanceLevel to be consistent.
+	* XmlTextReader.cs, XmlTextReader2.cs : added get_Conformance for
+	  internal use. Removed unused fields.
+	* XmlInputStream.cs : updated NonBlockingStreamReader to the latest
+	  StreamReader (it is almost a copy).
+
 2005-12-08  Atsushi Enomoto <[email protected]>
 
 	* XmlTextReader.cs : avoid Char.IsSurrogate() and do it inside

+ 0 - 5
mcs/class/System.XML/System.Xml/XmlChar.cs

@@ -31,11 +31,6 @@
 
 namespace System.Xml
 {
-	// Now, "XmlChar" and "XmlConstructs" are made as equivalent, so
-	// I dicided to rename XmlConstruts class as "XmlChar" and use it
-	// for default build.
-	// However, this class will be used for the future compact framework 
-	// (XmlConstruts class uses not a little memory).
 	internal class XmlChar
 	{
 		public static readonly char [] WhitespaceChars = new char [] {' ', '\n', '\t', '\r'};

+ 65 - 30
mcs/class/System.XML/System.Xml/XmlInputStream.cs

@@ -68,7 +68,8 @@ namespace System.Xml
 	#endregion
 
 	#region NonBlockingStreamReader
-	// mostly copied from StreamReader.
+	// mostly copied from StreamReader, removing BOM checks, ctor
+	// parameter checks and some extra public members.
 	internal class NonBlockingStreamReader : TextReader {
 
 		const int DefaultBufferSize = 1024;
@@ -105,6 +106,7 @@ namespace System.Xml
 
 		Stream base_stream;
 		bool mayBlock;
+		StringBuilder line_builder;
 
 		public NonBlockingStreamReader(Stream stream, Encoding encoding)
 		{
@@ -142,6 +144,11 @@ namespace System.Xml
 		{
 			pos = decoded_count = 0;
 			mayBlock = false;
+#if NET_2_0
+			decoder.Reset ();
+#else
+			decoder = encoding.GetDecoder ();
+#endif
 		}
 		
 		// the buffer is empty, fill it again
@@ -218,47 +225,75 @@ namespace System.Xml
 			return chars_read;
 		}
 
+		bool foundCR;
+		int FindNextEOL ()
+		{
+			char c = '\0';
+			for (; pos < decoded_count; pos++) {
+				c = decoded_buffer [pos];
+				if (c == '\n') {
+					pos++;
+					int res = (foundCR) ? (pos - 2) : (pos - 1);
+					if (res < 0)
+						res = 0; // if a new buffer starts with a \n and there was a \r at
+							// the end of the previous one, we get here.
+					foundCR = false;
+					return res;
+				} else if (foundCR) {
+					foundCR = false;
+					return pos - 1;
+				}
+
+				foundCR = (c == '\r');
+			}
+
+			return -1;
+		}
+
 		public override string ReadLine()
 		{
 			if (base_stream == null)
 				throw new ObjectDisposedException ("StreamReader", "Cannot read from a closed StreamReader");
-			
-			bool foundCR = false;
-			StringBuilder text = new StringBuilder ();
 
-			while (true) {
-				int c = Read ();
+			if (pos >= decoded_count && ReadBuffer () == 0)
+				return null;
 
-				if (c == -1) {				// end of stream
-					if (text.Length == 0)
-						return null;
+			int begin = pos;
+			int end = FindNextEOL ();
+			if (end < decoded_count && end >= begin)
+				return new string (decoded_buffer, begin, end - begin);
 
-					if (foundCR)
-						text.Length--;
+			if (line_builder == null)
+				line_builder = new StringBuilder ();
+			else
+				line_builder.Length = 0;
 
-					break;
+			while (true) {
+				if (foundCR) // don't include the trailing CR if present
+					decoded_count--;
+
+				line_builder.Append (new string (decoded_buffer, begin, decoded_count - begin));
+				if (ReadBuffer () == 0) {
+					if (line_builder.Capacity > 32768) {
+						StringBuilder sb = line_builder;
+						line_builder = null;
+						return sb.ToString (0, sb.Length);
+					}
+					return line_builder.ToString (0, line_builder.Length);
 				}
 
-				if (c == '\n') {			// newline
-					if ((text.Length > 0) && (text [text.Length - 1] == '\r'))
-						text.Length--;
-
-					foundCR = false;
-					break;
-				} else if (foundCR) {
-					pos--;
-					text.Length--;
-					break;
+				begin = pos;
+				end = FindNextEOL ();
+				if (end < decoded_count && end >= begin) {
+					line_builder.Append (new string (decoded_buffer, begin, end - begin));
+					if (line_builder.Capacity > 32768) {
+						StringBuilder sb = line_builder;
+						line_builder = null;
+						return sb.ToString (0, sb.Length);
+					}
+					return line_builder.ToString (0, line_builder.Length);
 				}
-
-				if (c == '\r')
-					foundCR = true;
-					
-
-				text.Append ((char) c);
 			}
-
-			return text.ToString ();
 		}
 
 		public override string ReadToEnd()

+ 26 - 16
mcs/class/System.XML/System.Xml/XmlReader.cs

@@ -275,37 +275,39 @@ namespace System.Xml
 			return Create (reader, settings, String.Empty);
 		}
 
+		static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
+		{
+			if (src == null)
+				return new XmlReaderSettings ();
+			else
+				return src.Clone ();
+		}
+
 		public static XmlReader Create (Stream stream, XmlReaderSettings settings, string baseUri)
 		{
-			if (settings == null)
-				settings = new XmlReaderSettings ();
+			settings = PopulateSettings (settings);
 			return Create (stream, settings,
 				PopulateParserContext (settings, baseUri));
 		}
 
 		public static XmlReader Create (TextReader reader, XmlReaderSettings settings, string baseUri)
 		{
-			if (settings == null)
-				settings = new XmlReaderSettings ();
+			settings = PopulateSettings (settings);
 			return Create (reader, settings,
 				PopulateParserContext (settings, baseUri));
 		}
 
-		[MonoTODO ("ConformanceLevel")]
 		public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
 		{
-			if (settings == null)
-				settings = new XmlReaderSettings ();
+			settings = PopulateSettings (settings);
 			XmlReader r = CreateFilteredXmlReader (reader, settings);
 			r.settings = settings;
 			return r;
 		}
 
-		[MonoTODO ("ConformanceLevel")]
 		public static XmlReader Create (string url, XmlReaderSettings settings, XmlParserContext context)
 		{
-			if (settings == null)
-				settings = new XmlReaderSettings ();
+			settings = PopulateSettings (settings);
 			if (context == null)
 				context = PopulateParserContext (settings, url);
 			return CreateCustomizedTextReader (
@@ -313,21 +315,17 @@ namespace System.Xml
 				settings);
 		}
 
-		[MonoTODO ("ConformanceLevel")]
 		public static XmlReader Create (Stream stream, XmlReaderSettings settings, XmlParserContext context)
 		{
-			if (settings == null)
-				settings = new XmlReaderSettings ();
+			settings = PopulateSettings (settings);
 			if (context == null)
 				context = PopulateParserContext (settings, String.Empty);
 			return CreateCustomizedTextReader (new XmlTextReader (stream, GetNodeType (settings), context), settings);
 		}
 
-		[MonoTODO ("ConformanceLevel")]
 		public static XmlReader Create (TextReader reader, XmlReaderSettings settings, XmlParserContext context)
 		{
-			if (settings == null)
-				settings = new XmlReaderSettings ();
+			settings = PopulateSettings (settings);
 			if (context == null)
 				context = PopulateParserContext (settings, String.Empty);
 			return CreateCustomizedTextReader (new XmlTextReader (context.BaseURI, reader, GetNodeType (settings), context), settings);
@@ -373,6 +371,18 @@ namespace System.Xml
 
 		private static XmlReader CreateFilteredXmlReader (XmlReader reader, XmlReaderSettings settings)
 		{
+			ConformanceLevel conf = ConformanceLevel.Auto;
+			if (reader is XmlTextReader)
+				conf = ((XmlTextReader) reader).Conformance;
+			else if (reader.Settings != null)
+				conf = reader.Settings.ConformanceLevel;
+			else
+				conf = settings.ConformanceLevel;
+			if (settings.ConformanceLevel != ConformanceLevel.Auto &&
+				conf != settings.ConformanceLevel)
+				throw new InvalidOperationException (String.Format ("ConformanceLevel cannot be overwritten by a wrapping XmlReader. The source reader has {0}, while {1} is specified.", conf, settings.ConformanceLevel));
+			settings.ConformanceLevel = conf;
+
 			reader = CreateValidatingXmlReader (reader, settings);
 
 			if (reader.Settings != null ||

+ 1 - 1
mcs/class/System.XML/System.Xml/XmlTextReader.cs

@@ -1025,8 +1025,8 @@ namespace System.Xml
 		}
 
 #if NET_2_0
-		[MonoTODO ("Test")]
 		internal ConformanceLevel Conformance {
+			get { return allowMultipleRoot ? ConformanceLevel.Fragment : ConformanceLevel.Document; }
 			set {
 				if (value == ConformanceLevel.Fragment) {
 					currentState = XmlNodeType.Element;

+ 1 - 2
mcs/class/System.XML/System.Xml/XmlTextReader2.cs

@@ -48,8 +48,6 @@ namespace System.Xml
 		XmlTextReaderImpl source;
 		bool entityInsideAttribute;
 		bool insideAttribute;
-		string cachedAttributeValue;
-		bool attributeValueConsumed;
 
 		protected XmlTextReader ()
 		{
@@ -286,6 +284,7 @@ namespace System.Xml
 		}
 
 		internal ConformanceLevel Conformance {
+			get { return source.Conformance; }
 			set {
 				if (entity != null)
 					entity.Conformance = value;

+ 6 - 0
mcs/class/System.XML/Test/System.Xml/ChangeLog

@@ -1,3 +1,9 @@
+2005-12-09  Atsushi Enomoto <[email protected]>
+
+	* XmlReaderSettingsTests.cs : added some ConformanceLevel tests.
+	  Added CreateClonesSettings() to make sure XmlReader.Create() clones
+	  XmlReaderSettings.
+
 2005-12-08  Atsushi Enomoto <[email protected]>
 
 	* XmlReaderSettingsTests.cs : (DefaultValue)

+ 124 - 0
mcs/class/System.XML/Test/System.Xml/XmlReaderSettingsTests.cs

@@ -16,6 +16,7 @@ using System.Xml.Schema;
 using NUnit.Framework;
 
 using ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags;
+using AssertType = NUnit.Framework.Assert;
 
 namespace MonoTests.System.Xml
 {
@@ -169,6 +170,129 @@ namespace MonoTests.System.Xml
 			XmlReader.Create (CreateStream ("<root/>"), s, (XmlParserContext) null)
 				.Read ();
 		}
+
+		#region ConformanceLevel
+
+		[Test]
+		public void InferConformanceLevel ()
+		{
+			XmlReader xr = XmlReader.Create (new StringReader ("<foo/><bar/>"));
+			
+			AssertType.AreEqual (ConformanceLevel.Document, xr.Settings.ConformanceLevel);
+		}
+
+		[Test]
+		public void InferWrappedReaderConformance ()
+		{
+			// Actually this test is weird, since XmlTextReader
+			// instance here does not have XmlReaderSettings.
+			XmlReaderSettings settings = new XmlReaderSettings ();
+			settings.ConformanceLevel = ConformanceLevel.Auto;
+			XmlReader xr = XmlReader.Create (
+				XmlReader.Create (new StringReader ("<foo/><bar/>")),
+				settings);
+			AssertType.AreEqual (ConformanceLevel.Document, xr.Settings.ConformanceLevel);
+		}
+
+		[Test]
+		[ExpectedException (typeof (XmlException))]
+		public void CreateConformanceDocument ()
+		{
+			XmlReaderSettings s = new XmlReaderSettings ();
+			s.ConformanceLevel = ConformanceLevel.Document;
+			XmlReader xr = XmlReader.Create (new StringReader (
+				"<foo/><bar/>"), s);
+			while (!xr.EOF)
+				xr.Read ();
+		}
+
+		[Test]
+		public void CreateConformanceFragment ()
+		{
+			XmlReaderSettings settings = new XmlReaderSettings ();
+			settings.ConformanceLevel = ConformanceLevel.Fragment;
+			XmlReader xr = XmlReader.Create (new StringReader (
+				"<foo/><bar/>"), settings);
+			while (!xr.EOF)
+				xr.Read ();
+		}
+
+		[Test]
+		[ExpectedException (typeof (InvalidOperationException))]
+		public void CreateConformanceChangeToDocument ()
+		{
+			// Actually this test is weird, since XmlTextReader
+			// instance here does not have XmlReaderSettings.
+			XmlReaderSettings settings = new XmlReaderSettings ();
+			settings.ConformanceLevel = ConformanceLevel.Document;
+			XmlReader xr = XmlReader.Create (
+				new XmlTextReader ("<foo/><bar/>", XmlNodeType.Element, null),
+				settings);
+			while (!xr.EOF)
+				xr.Read ();
+		}
+
+		[Test]
+		[ExpectedException (typeof (InvalidOperationException))]
+		public void CreateConformanceChangeToFragment ()
+		{
+			// Actually this test is weird, since XmlTextReader
+			// instance here does not have XmlReaderSettings.
+			XmlReaderSettings settings = new XmlReaderSettings ();
+			settings.ConformanceLevel = ConformanceLevel.Fragment;
+			XmlReader xr = XmlReader.Create (
+				new XmlTextReader ("<foo/>", XmlNodeType.Document, null),
+				settings);
+			while (!xr.EOF)
+				xr.Read ();
+		}
+
+		[Test]
+		public void CreateConformanceLevelExplicitAuto ()
+		{
+			// Even if we specify ConformanceLevel.Auto explicitly,
+			// XmlTextReader's ConformanceLevel becomes .Document.
+			XmlReaderSettings settings = new XmlReaderSettings ();
+			settings.ConformanceLevel = ConformanceLevel.Auto;
+			XmlReader xr = XmlReader.Create (
+				new XmlTextReader ("<foo/>", XmlNodeType.Document, null),
+				settings);
+			AssertType.AreEqual (ConformanceLevel.Document, xr.Settings.ConformanceLevel);
+		}
+
+		[Test]
+		public void CreateKeepConformance ()
+		{
+			XmlReaderSettings settings;
+			XmlReader xr;
+
+			// Fragment -> Fragment
+			settings = new XmlReaderSettings ();
+			settings.ConformanceLevel = ConformanceLevel.Fragment;
+			xr = XmlReader.Create (
+				XmlReader.Create (new StringReader ("<foo/>"), settings),
+				settings);
+			while (!xr.EOF)
+				xr.Read ();
+
+			// Document -> Document
+			settings.ConformanceLevel = ConformanceLevel.Document;
+			xr = XmlReader.Create (
+				XmlReader.Create (new StringReader ("<foo/>"), settings),
+				settings);
+			while (!xr.EOF)
+				xr.Read ();
+		}
+
+		#endregion
+
+		[Test]
+		public void CreateClonesSettings ()
+		{
+			XmlReaderSettings settings = new XmlReaderSettings ();
+			XmlReader xr = XmlReader.Create (new StringReader ("<doc/>"), settings);
+			AssertType.IsFalse (Object.ReferenceEquals (settings, xr.Settings));
+		}
 	}
 }
 #endif