| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- //
- // XPathSequence.cs - represents XPath sequence iterator
- //
- // Author:
- // Atsushi Enomoto <[email protected]>
- //
- //
- // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if NET_2_0
- using System;
- using System.Collections;
- using System.Xml;
- using System.Xml.Schema;
- using System.Xml.Query;
- using System.Xml.XPath;
- namespace Mono.Xml.XPath2
- {
- public abstract class XPathSequence : IEnumerable, ICloneable
- {
- XQueryContext ctx;
- int countCache = -1;
- int position = 0;
- internal XPathSequence (XQueryContext ctx)
- {
- this.ctx = ctx;
- }
- internal XPathSequence (XPathSequence original)
- {
- ctx = original.ctx;
- position = original.position;
- }
- internal XQueryContext Context {
- get { return ctx; }
- }
- public virtual int Count {
- get {
- if (countCache >= 0)
- return countCache;
- XPathSequence clone = Clone ();
- countCache = 0;
- while (clone.MoveNext ())
- countCache++;
- return countCache;
- }
- }
- public XPathItem Current {
- get {
- if (Position == 0)
- throw new InvalidOperationException ("XQuery internal error (should not happen)");
- return CurrentCore;
- }
- }
- public abstract XPathItem CurrentCore { get; }
- // Returns 0 if not started, otherwise returns XPath positional integer.
- public int Position {
- get { return position; }
- }
- public bool MoveNext ()
- {
- if (!MoveNextCore ())
- return false;
- position++;
- return true;
- }
- public abstract bool MoveNextCore ();
- public abstract XPathSequence Clone ();
- object ICloneable.Clone ()
- {
- return this.Clone ();
- }
- public virtual IEnumerator GetEnumerator ()
- {
- while (MoveNext ())
- yield return CurrentCore;
- }
- }
- // empty iterator (still required since it contains XQueryContext)
- class XPathEmptySequence : XPathSequence
- {
- internal XPathEmptySequence (XPathSequence iter)
- : base (iter.Context)
- {
- }
- public override int Count {
- get { return 0; }
- }
- public override bool MoveNextCore ()
- {
- return false;
- }
- public override XPathItem CurrentCore {
- get { throw new InvalidOperationException ("Should not happen. In XPathEmptySequence.Current."); }
- }
- // Don't return clone
- public override XPathSequence Clone ()
- {
- return this;
- }
- }
- // single item iterator
- internal class SingleItemIterator : XPathSequence
- {
- XPathItem item;
- XPathItem current;
- public SingleItemIterator (XPathItem item, XPathSequence iter)
- : this (item, iter.Context)
- {
- }
- // for XQuery execution start point
- internal SingleItemIterator (XPathItem item, XQueryContext ctx)
- : base (ctx)
- {
- this.item = item;
- }
- private SingleItemIterator (SingleItemIterator other)
- : base (other)
- {
- this.item = other.item;
- this.current = other.current;
- }
- public override XPathSequence Clone ()
- {
- return new SingleItemIterator (this);
- }
- public override bool MoveNextCore ()
- {
- if (item != null) {
- current = item;
- item = null;
- return true;
- }
- return false;
- }
- public override XPathItem CurrentCore {
- get {
- return current;
- }
- }
- }
- // RangeExpr iterator
- internal class IntegerRangeIterator : XPathSequence
- {
- static XmlSchemaSimpleType intType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("int", XmlSchema.Namespace));
- int start;
- int end;
- int next;
- XPathItem current;
- public IntegerRangeIterator (XPathSequence iter, int start, int end)
- : base (iter.Context)
- {
- this.start = start;
- this.end = end;
- }
- private IntegerRangeIterator (IntegerRangeIterator other)
- : base (other)
- {
- this.start = other.start;
- this.end = other.end;
- this.next = other.next;
- this.current = other.current;
- }
- public override XPathSequence Clone ()
- {
- return new IntegerRangeIterator (this);
- }
- public override bool MoveNextCore ()
- {
- if (current == null)
- next = start;
- if (next > end)
- return false;
- current = new XPathAtomicValue (next++, intType);
- return true;
- }
- public override XPathItem CurrentCore {
- get {
- return current;
- }
- }
- }
- // Slash iterator
- internal class ChildPathIterator : XPathSequence
- {
- XPathSequence left;
- ExprSingle child;
- public ChildPathIterator (XPathSequence iter, PathChildExpr source)
- : base (iter.Context)
- {
- left = source.Left.Evaluate (iter);
- child = source.Next;
- }
- private ChildPathIterator (ChildPathIterator other)
- : base (other)
- {
- left = other.left.Clone ();
- child = other.child;
- }
- public override XPathSequence Clone ()
- {
- return new ChildPathIterator (this);
- }
- public override bool MoveNextCore ()
- {
- throw new NotImplementedException ();
- }
- public override XPathItem CurrentCore {
- get { return left.Current; }
- }
- }
- // Slash2 iterator
- internal class DescendantPathIterator : XPathSequence
- {
- XPathSequence left;
- ExprSingle descendant;
- public DescendantPathIterator (XPathSequence iter, PathDescendantExpr source)
- : base (iter.Context)
- {
- left = source.Left.Evaluate (iter);
- descendant = source.Descendant;
- }
- private DescendantPathIterator (DescendantPathIterator other)
- : base (other)
- {
- left = other.left.Clone ();
- descendant = other.descendant;
- }
- public override XPathSequence Clone ()
- {
- return new DescendantPathIterator (this);
- }
- public override bool MoveNextCore ()
- {
- throw new NotImplementedException ();
- }
- public override XPathItem CurrentCore {
- get { return left.Current; }
- }
- }
- // Filter step iterator
- internal class FilteredIterator : XPathSequence
- {
- XPathSequence left;
- PredicateList filter;
- public FilteredIterator (XPathSequence iter, FilterStepExpr source)
- : base (iter.Context)
- {
- left = source.Expr.Evaluate (iter);
- filter = source.Predicates;
- }
- private FilteredIterator (FilteredIterator other)
- : base (other)
- {
- left = other.left.Clone ();
- filter = other.filter;
- }
- public override XPathSequence Clone ()
- {
- return new FilteredIterator (this);
- }
- public override bool MoveNextCore ()
- {
- throw new NotImplementedException ();
- }
- public override XPathItem CurrentCore {
- get { return left.Current; }
- }
- }
- // AxisIterator
- internal class AxisIterator : XPathSequence
- {
- XPathSequence iter;
- AxisStepExpr source;
- public AxisIterator (XPathSequence iter, AxisStepExpr source)
- : base (iter.Context)
- {
- this.iter = iter;
- this.source = source;
- }
- private AxisIterator (AxisIterator other)
- : base (other)
- {
- iter = other.iter.Clone ();
- source = other.source;
- }
- public override XPathSequence Clone ()
- {
- return new AxisIterator (this);
- }
- public override bool MoveNextCore ()
- {
- throw new NotImplementedException ();
- }
- public override XPathItem CurrentCore {
- get { throw new NotImplementedException (); }
- }
- }
- /*
- // Node test iterator
- internal class NodeKindTestIterator : XPathSequence
- {
- XPathSequence iter;
- NodeKindTestExpression source;
- public NodeKindTestIterator (XPathSequence iter, NodeKindTestExpression source)
- : base (iter.Context)
- {
- this.iter = iter;
- this.source = source;
- }
- private NodeKindTestIterator (NodeKindTestIterator other)
- : base (other)
- {
- iter = other.iter.Clone ();
- source = other.source;
- }
- public override XPathSequence Clone ()
- {
- return new NodeKindTestIterator (this);
- }
- public override bool MoveNextCore ()
- {
- throw new NotImplementedException ();
- }
- public override XPathItem CurrentCore {
- get { throw new NotImplementedException (); }
- }
- }
- */
- internal class ExprSequenceIterator : XPathSequence
- {
- XPathSequence contextSequence;
- XPathSequence iter;
- ExprSequence expr;
- int currentExprIndex;
- public ExprSequenceIterator (XPathSequence iter, ExprSequence expr)
- : base (iter.Context)
- {
- contextSequence = iter;
- this.expr = expr;
- }
- private ExprSequenceIterator (ExprSequenceIterator other)
- : base (other)
- {
- if (other.iter != null)
- iter = other.iter.Clone ();
- expr = other.expr;
- currentExprIndex = other.currentExprIndex;
- }
- public override XPathSequence Clone ()
- {
- return new ExprSequenceIterator (this);
- }
- public override bool MoveNextCore ()
- {
- if (iter != null && iter.MoveNext ())
- return true;
- for (; currentExprIndex < expr.Count; currentExprIndex++) {
- iter = expr [currentExprIndex].Evaluate (contextSequence);
- if (iter.MoveNext ())
- return true;
- }
- return false;
- }
- public override XPathItem CurrentCore {
- get { return iter.Current; }
- }
- }
- internal class FLWORIterator : XPathSequence
- {
- XPathSequence contextSequence;
- FLWORExpr expr;
- public FLWORIterator (XPathSequence iter, FLWORExpr expr)
- : base (iter.Context)
- {
- this.contextSequence = iter;
- this.expr = expr;
- }
- private FLWORIterator (FLWORIterator other)
- : base (other)
- {
- contextSequence = other.contextSequence;
- expr = other.expr;
- throw new NotImplementedException ();
- }
- public override XPathSequence Clone ()
- {
- return new FLWORIterator (this);
- }
- public override bool MoveNextCore ()
- {
- throw new NotImplementedException ();
- }
- public override XPathItem CurrentCore {
- get { throw new NotImplementedException (); }
- }
- }
- internal class AtomizingIterator : XPathSequence
- {
- XPathSequence iter;
- public AtomizingIterator (XPathSequence iter)
- : base (iter.Context)
- {
- this.iter = iter;
- }
- private AtomizingIterator (AtomizingIterator other)
- : base (other)
- {
- iter = other.iter.Clone ();
- }
- public override XPathSequence Clone ()
- {
- return new AtomizingIterator (this);
- }
- public override bool MoveNextCore ()
- {
- return iter.MoveNext ();
- }
- public override XPathItem CurrentCore {
- get {
- XPathNavigator nav = iter.Current as XPathNavigator;
- if (nav == null)
- return (XPathAtomicValue) iter.Current;
- if (nav.SchemaInfo != null)
- return new XPathAtomicValue (
- nav.TypedValue,
- nav.SchemaInfo.SchemaType);
- else
- return new XPathAtomicValue (nav.Value, null);
- }
- }
- }
- internal class ConvertingIterator : XPathSequence
- {
- XPathSequence iter;
- SequenceType type;
- public ConvertingIterator (XPathSequence iter, SequenceType type)
- : base (iter.Context)
- {
- this.iter = iter;
- type = type;
- }
- private ConvertingIterator (ConvertingIterator other)
- : base (other)
- {
- iter = other.iter.Clone ();
- type = other.type;
- }
- public override XPathSequence Clone ()
- {
- return new ConvertingIterator (this);
- }
- public override bool MoveNextCore ()
- {
- return iter.MoveNext ();
- }
- public override XPathItem CurrentCore {
- get { return type.Convert (iter.Current); }
- }
- }
- internal class TracingIterator : XPathSequence
- {
- XPathSequence iter;
- string format;
- public TracingIterator (XPathSequence iter, string format)
- : base (iter.Context)
- {
- this.iter = iter;
- this.format = format;
- }
- private TracingIterator (TracingIterator other)
- : base (other)
- {
- iter = other.iter.Clone ();
- format = other.format;
- }
- public override XPathSequence Clone ()
- {
- return new TracingIterator (this);
- }
- public override bool MoveNextCore ()
- {
- if (!iter.MoveNext ())
- return false;
- // FIXME: use OnMessageEvent
- // Context.ErrorOutput.Write (format, iter.Current.TypedValue);
- throw new NotImplementedException ();
- return true;
- }
- public override XPathItem CurrentCore {
- get { return iter.Current; }
- }
- }
- internal class ListIterator : XPathSequence
- {
- IList list;
- public ListIterator (XPathSequence iter, IList list)
- : base (iter.Context)
- {
- if (list is ICloneable)
- this.list = list;
- else
- throw new InvalidOperationException (String.Format ("XQuery internal error: target list is not cloneable. List is {0}.", list != null ? list.GetType ().ToString () : "null argument"));
- }
- private ListIterator (ListIterator other)
- : base (other)
- {
- this.list = (IList) ((ICloneable) other.list).Clone ();
- }
- public override XPathSequence Clone ()
- {
- return new ListIterator (this);
- }
- public override bool MoveNextCore ()
- {
- return (Position < list.Count);
- }
- public override XPathItem CurrentCore {
- get { return (XPathItem) list [Position - 1]; }
- }
- }
- }
- #endif
|