[Mono-patches] mcs/class/System.XML/System.Xml.Query XPath2Expression.cs,1.15,1.16 XPathSequence.cs,1.8,1.9 XQueryExpression.cs,1.6,1.7 XQueryFunction.cs,1.7,1.8 XQueryFunctionCliImpl.cs,1.5,1.6 XmlQueryException.cs,1.5,1.6 ChangeLog,1.25,1.26

Atsushi Enomoto ginga@kit.hi-ho.ne.jp atsushi@mono-cvs.ximian.com
Tue, 31 Aug 2004 13:34:26 -0400 (EDT)


Update of /cvs/public/mcs/class/System.XML/System.Xml.Query
In directory mono-cvs.ximian.com:/tmp/cvs-serv28160

Modified Files:
	XPath2Expression.cs XPathSequence.cs XQueryExpression.cs 
	XQueryFunction.cs XQueryFunctionCliImpl.cs 
	XmlQueryException.cs ChangeLog 
Log Message:
2004-08-31  Atsushi Enomoto <atsushi@ximian.com>

	* XPath2Expression.cs,
	  XPathSequence.cs :
	  Implemented GroupExpr.Evaluate() [union/intersect/except].
	  Fixed incorrect iterator input for DescendantExpr.Evaluate().
	  MinusExpr is (already) implemented not to be evaluated.
	* XQueryExpression.cs :
	  PI name and nameExpr could be implemented.
	* XQueryFunction.cs :
	  UserFunctionCallExpr.Invoke() should not be invoked.
	* XQueryFunctionCliImpl.cs :
	  Implemented count(), doc(). Halfly implemented trace().
	* XmlQueryException.cs : Serializable.



Index: XPath2Expression.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.XML/System.Xml.Query/XPath2Expression.cs,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- XPath2Expression.cs	31 Aug 2004 16:01:09 -0000	1.15
+++ XPath2Expression.cs	31 Aug 2004 17:34:24 -0000	1.16
@@ -1485,7 +1485,7 @@
 
 		public override XPathSequence Evaluate (XPathSequence iter)
 		{
-			throw new NotImplementedException ();
+			throw new SystemException ("XQuery internal error: should not happen.");
 		}
 #endregion
 	}
@@ -1528,17 +1528,7 @@
 		// only applicable against node-sets
 		public override XPathSequence Evaluate (XPathSequence iter)
 		{
-			XPathSequence lvalue = Left.EvaluateOrdered (iter);
-			XPathSequence rvalue = Right.EvaluateOrdered (iter);
-
-			/*
-			TBD (yield earlier node, skipping one of the same nodes)
-				- or -
-			TBD (yield earlier node, skipping non-intersection nodes)
-				- or -
-			TBD (yield earlier node, skipping both of the same nodes)
-			*/
-			throw new NotImplementedException ();
+			return new GroupIterator (iter, this);
 		}
 #endregion
 	}
@@ -1705,7 +1695,7 @@
 			if (!seq.MoveNext ())
 				return new XPathEmptySequence (iter.Context);
 			return new PathStepIterator (
-				new DescendantOrSelfIterator (iter.Current as XPathNavigator, iter.Context), this);
+				new DescendantOrSelfIterator (seq.Current as XPathNavigator, seq.Context), this);
 		}
 #endregion
 	}

Index: XPathSequence.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.XML/System.Xml.Query/XPathSequence.cs,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- XPathSequence.cs	31 Aug 2004 14:23:49 -0000	1.8
+++ XPathSequence.cs	31 Aug 2004 17:34:24 -0000	1.9
@@ -1313,6 +1313,120 @@
 		}
 	}
 
+	internal class GroupIterator : XPathSequence
+	{
+		GroupExpr expr;
+		XPathSequence lseq;
+		XPathSequence rseq;
+		bool started;
+		bool left;
+		bool leftFinished;
+		bool rightFinished;
+
+		public GroupIterator (XPathSequence iter, GroupExpr expr)
+			: base (iter.Context)
+		{
+			this.expr = expr;
+			left = true;
+			lseq = expr.Left.EvaluateOrdered (iter);
+			rseq = expr.Right.EvaluateOrdered (iter);
+		}
+
+		private GroupIterator (GroupIterator other)
+			: base (other)
+		{
+			this.expr = other.expr;
+			this.started = other.started;
+			this.left = other.left;
+			this.leftFinished = other.leftFinished;
+			this.rightFinished = other.rightFinished;
+			this.lseq = other.lseq.Clone ();
+			this.rseq = other.rseq.Clone ();
+		}
+
+		public override XPathSequence Clone ()
+		{
+			return new GroupIterator (this);
+		}
+
+		protected override bool MoveNextCore ()
+		{
+			if (leftFinished && rightFinished)
+				return false;
+			bool proceeded = false;
+			if (started) {
+				if (left) {
+					if (!leftFinished && lseq.MoveNext ())
+						proceeded = true;
+					else
+						leftFinished = true;
+				} else {
+					if (rightFinished && rseq.MoveNext ())
+						proceeded = true;
+					else
+						rightFinished = true;
+				}
+			} else {
+				started = true;
+				if (!lseq.MoveNext ()) {
+					leftFinished = true;
+					if (!rseq.MoveNext ()) {
+						rightFinished = true;
+						return false;
+					}
+					left = false;
+					return true;
+				}
+				proceeded = true;
+				if (!rseq.MoveNext ()) {
+					rightFinished = true;
+					return true;
+				}
+			}
+			if (!proceeded) {
+				if (expr.AggregationType == AggregationType.Intersect)
+					return false;
+				left = !leftFinished;
+				return !leftFinished || !rightFinished;
+			}
+
+			XPathNavigator lnav = lseq.Current as XPathNavigator;
+			XPathNavigator rnav = rseq.Current as XPathNavigator;
+			if (lnav == null || rnav == null)
+				throw new XmlQueryException ("XP0006: Evaluation against union, intersect, except expressions must result in nodes.");
+			XmlNodeOrder order = lnav.ComparePosition (rnav);
+			switch (order) {
+			case XmlNodeOrder.Same:
+				switch (expr.AggregationType) {
+				case AggregationType.Union:
+					left = false;
+					if (!lseq.MoveNext ())
+						leftFinished = true;
+					return true;
+				case AggregationType.Intersect:
+					return true;
+				case AggregationType.Except:
+				default:
+					return MoveNext ();
+				}
+			case XmlNodeOrder.Before:
+				left = true;
+				if (expr.AggregationType == AggregationType.Intersect)
+					return MoveNext ();
+				return true;
+			default: // After, Unknown
+				left = false;
+				if (expr.AggregationType == AggregationType.Intersect)
+					return MoveNext ();
+				return true;
+			}
+		}
+
+		public override XPathItem CurrentCore {
+			get { return left ? lseq.Current : rseq.Current; }
+		}
+	}
+
 	internal class AtomizingIterator : XPathSequence
 	{
 		XPathSequence iter;

Index: XQueryExpression.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.XML/System.Xml.Query/XQueryExpression.cs,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- XQueryExpression.cs	31 Aug 2004 14:23:49 -0000	1.6
+++ XQueryExpression.cs	31 Aug 2004 17:34:24 -0000	1.7
@@ -541,10 +541,11 @@
 		}
 
 		public string Name {
-			get { throw new NotImplementedException (); }
+			get { return name; }
 		}
+
 		public ExprSequence NameExpr {
-			get { throw new NotImplementedException (); }
+			get { return nameExpr; }
 		}
 
 		// FIXME: can be optimized by checking all items in Expr

Index: XQueryFunction.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.XML/System.Xml.Query/XQueryFunction.cs,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- XQueryFunction.cs	31 Aug 2004 14:23:49 -0000	1.7
+++ XQueryFunction.cs	31 Aug 2004 17:34:24 -0000	1.8
@@ -302,7 +302,7 @@
 
 		public override object Invoke (XQueryContext context, object [] args)
 		{
-			throw new NotImplementedException ("Not supported");
+			throw new SystemException ("XQuery internal error: should not happen.");
 		}
 
 		public override XPathSequence Evaluate (XPathSequence iter, ExprSequence args)

Index: XQueryFunctionCliImpl.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.XML/System.Xml.Query/XQueryFunctionCliImpl.cs,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- XQueryFunctionCliImpl.cs	26 Aug 2004 02:27:48 -0000	1.5
+++ XQueryFunctionCliImpl.cs	31 Aug 2004 17:34:24 -0000	1.6
@@ -36,6 +36,7 @@
 using System;
 using System.Collections;
 using System.Globalization;
+using System.IO;
 using System.Text.RegularExpressions;
 using System.Xml;
 using System.Xml.Query;
@@ -170,9 +171,26 @@
 		// Trace
 
 		[MonoTODO]
-		public static object FnTrace (object arg)
+		public static object FnTrace (XQueryContext ctx, object value, string label)
 		{
-			throw new NotImplementedException ();
+			if (value == null)
+				return new XPathEmptySequence (ctx);
+			XPathSequence seq = value as XPathSequence;
+			if (seq == null) {
+				IEnumerable list = value as IEnumerable;
+				if (list != null)
+					seq = new EnumeratorIterator (ctx, list);
+				else {
+					XPathAtomicValue av = value as XPathAtomicValue;
+					if (av == null)
+						av = new XPathAtomicValue (value,
+							XmlSchemaType.GetBuiltInType (
+								XPathAtomicValue.XmlTypeCodeFromRuntimeType (
+									value.GetType (), true)));
+					seq = new SingleItemIterator (av, ctx);
+				}
+			}
+			return new TracingIterator (seq, label);
 		}
 
 		// Numeric Operation
@@ -704,10 +722,21 @@
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
-		public static object FnCount (IEnumerable e)
+		public static int FnCount (IEnumerable e)
 		{
-			throw new NotImplementedException ();
+			if (e == null)
+				return 0;
+			XPathSequence seq = e as XPathSequence;
+			if (seq != null)
+				return seq.Count;
+			ICollection col = e as ICollection;
+			if (col != null)
+				return col.Count;
+			int count = 0;
+			IEnumerator en = e.GetEnumerator ();
+			while (en.MoveNext ())
+				count++;
+			return count;
 		}
 
 		[MonoTODO]
@@ -775,10 +804,21 @@
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
-		public static object FnDoc (XQueryContext ctx, string uri)
+		public static XPathNavigator FnDoc (XQueryContext ctx, string uri)
 		{
-			throw new NotImplementedException ();
+			XmlResolver res = ctx.ContextManager.ExtDocResolver;
+			string baseUriString = ctx.StaticContext.BaseUri;
+			Uri baseUri = null;
+			if (baseUriString != null && baseUriString != String.Empty)
+				baseUri = new Uri (baseUriString);
+			Uri relUri = res.ResolveUri (baseUri, uri);
+			Stream s = res.GetEntity (relUri, null, typeof (Stream)) as Stream;
+			try {
+				XPathDocument doc = new XPathDocument (new XmlValidatingReader (new XmlTextReader (s)), XmlSpace.Preserve);
+				return doc.CreateNavigator ();
+			} finally {
+				s.Close ();
+			}
 		}
 
 		public static IEnumerable FnCollection (XQueryContext ctx, string name)

Index: XmlQueryException.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.XML/System.Xml.Query/XmlQueryException.cs,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- XmlQueryException.cs	23 Jul 2004 16:03:50 -0000	1.5
+++ XmlQueryException.cs	31 Aug 2004 17:34:24 -0000	1.6
@@ -35,6 +35,7 @@
 
 namespace System.Xml.Query
 {
+	[Serializable]
 	public class XmlQueryException : SystemException
 	{
 		#region Constructors

Index: ChangeLog
===================================================================
RCS file: /cvs/public/mcs/class/System.XML/System.Xml.Query/ChangeLog,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- ChangeLog	31 Aug 2004 16:01:09 -0000	1.25
+++ ChangeLog	31 Aug 2004 17:34:24 -0000	1.26
@@ -1,5 +1,20 @@
 2004-08-31  Atsushi Enomoto <atsushi@ximian.com>
 
+	* XPath2Expression.cs,
+	  XPathSequence.cs :
+	  Implemented GroupExpr.Evaluate() [union/intersect/except].
+	  Fixed incorrect iterator input for DescendantExpr.Evaluate().
+	  MinusExpr is (already) implemented not to be evaluated.
+	* XQueryExpression.cs :
+	  PI name and nameExpr could be implemented.
+	* XQueryFunction.cs :
+	  UserFunctionCallExpr.Invoke() should not be invoked.
+	* XQueryFunctionCliImpl.cs :
+	  Implemented count(), doc(). Halfly implemented trace().
+	* XmlQueryException.cs : Serializable.
+
+2004-08-31  Atsushi Enomoto <atsushi@ximian.com>
+
 	* XPath2Expression.cs :
 	  Implemented the whole ComparisonExpr.Evaluate(). It now handles
 	  empty sequence expectedly.