XPathSequence.cs 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336
  1. //
  2. // XPathSequence.cs - represents XPath sequence iterator
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. //
  8. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. #if NET_2_0
  30. using System;
  31. using System.Collections;
  32. using System.Xml;
  33. using System.Xml.Schema;
  34. using System.Xml.Query;
  35. using System.Xml.XPath;
  36. namespace Mono.Xml.XPath2
  37. {
  38. public abstract class XPathSequence : IEnumerable, ICloneable
  39. {
  40. XQueryContext ctx;
  41. int countCache = -1;
  42. int position = 0;
  43. internal XPathSequence (XQueryContext ctx)
  44. {
  45. this.ctx = ctx;
  46. }
  47. internal XPathSequence (XPathSequence original)
  48. {
  49. ctx = original.ctx;
  50. position = original.position;
  51. }
  52. internal XQueryContext Context {
  53. get { return ctx; }
  54. }
  55. public virtual int Count {
  56. get {
  57. if (countCache >= 0)
  58. return countCache;
  59. XPathSequence clone = Clone ();
  60. while (clone.MoveNext ())
  61. ;
  62. countCache = clone.Position;
  63. return countCache;
  64. }
  65. }
  66. public XPathItem Current {
  67. get {
  68. if (Position == 0)
  69. throw new InvalidOperationException ("XQuery internal error (should not happen)");
  70. return CurrentCore;
  71. }
  72. }
  73. public abstract XPathItem CurrentCore { get; }
  74. // Returns 0 if not started, otherwise returns XPath positional integer.
  75. public int Position {
  76. get { return position; }
  77. }
  78. public bool MoveNext ()
  79. {
  80. if (!MoveNextCore ())
  81. return false;
  82. position++;
  83. return true;
  84. }
  85. protected abstract bool MoveNextCore ();
  86. public abstract XPathSequence Clone ();
  87. object ICloneable.Clone ()
  88. {
  89. return this.Clone ();
  90. }
  91. public virtual IEnumerator GetEnumerator ()
  92. {
  93. while (MoveNext ())
  94. yield return CurrentCore;
  95. }
  96. }
  97. // empty iterator (still required since it contains XQueryContext)
  98. class XPathEmptySequence : XPathSequence
  99. {
  100. internal XPathEmptySequence (XPathSequence iter)
  101. : base (iter.Context)
  102. {
  103. }
  104. public override int Count {
  105. get { return 0; }
  106. }
  107. protected override bool MoveNextCore ()
  108. {
  109. return false;
  110. }
  111. public override XPathItem CurrentCore {
  112. get { throw new InvalidOperationException ("Should not happen. In XPathEmptySequence.Current."); }
  113. }
  114. // Don't return clone. It's waste of resource.
  115. public override XPathSequence Clone ()
  116. {
  117. return this;
  118. }
  119. }
  120. // single item iterator
  121. internal class SingleItemIterator : XPathSequence
  122. {
  123. XPathItem item;
  124. XPathItem current;
  125. public SingleItemIterator (XPathItem item, XPathSequence iter)
  126. : this (item, iter.Context)
  127. {
  128. }
  129. // for XQuery execution start point
  130. internal SingleItemIterator (XPathItem item, XQueryContext ctx)
  131. : base (ctx)
  132. {
  133. this.item = item;
  134. }
  135. private SingleItemIterator (SingleItemIterator other)
  136. : base (other)
  137. {
  138. this.item = other.item;
  139. this.current = other.current;
  140. }
  141. public override XPathSequence Clone ()
  142. {
  143. return new SingleItemIterator (this);
  144. }
  145. protected override bool MoveNextCore ()
  146. {
  147. if (current == null) {
  148. current = item;
  149. return true;
  150. }
  151. return false;
  152. }
  153. public override XPathItem CurrentCore {
  154. get {
  155. return current;
  156. }
  157. }
  158. }
  159. // RangeExpr iterator
  160. internal class IntegerRangeIterator : XPathSequence
  161. {
  162. static XmlSchemaSimpleType intType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("int", XmlSchema.Namespace));
  163. int start;
  164. int end;
  165. int next;
  166. XPathItem current;
  167. public IntegerRangeIterator (XPathSequence iter, int start, int end)
  168. : base (iter.Context)
  169. {
  170. this.start = start;
  171. this.end = end;
  172. }
  173. private IntegerRangeIterator (IntegerRangeIterator other)
  174. : base (other)
  175. {
  176. this.start = other.start;
  177. this.end = other.end;
  178. this.next = other.next;
  179. this.current = other.current;
  180. }
  181. public override XPathSequence Clone ()
  182. {
  183. return new IntegerRangeIterator (this);
  184. }
  185. protected override bool MoveNextCore ()
  186. {
  187. if (current == null)
  188. next = start;
  189. if (next > end)
  190. return false;
  191. current = new XPathAtomicValue (next++, intType);
  192. return true;
  193. }
  194. public override XPathItem CurrentCore {
  195. get {
  196. return current;
  197. }
  198. }
  199. }
  200. // Slash iterator
  201. // <copy original='System.Xml.XPath/Iterator.cs,
  202. // System.Xml.XPath/XPathComparer.cs'>
  203. internal class PathStepIterator : XPathSequence
  204. {
  205. XPathSequence left;
  206. XPathSequence right;
  207. PathStepExpr step;
  208. ArrayList nodeStore;
  209. SortedList storedIterators;
  210. bool finished;
  211. XPathSequence nextRight;
  212. public PathStepIterator (XPathSequence iter, PathStepExpr source)
  213. : base (iter.Context)
  214. {
  215. left = iter;
  216. step = source;
  217. }
  218. private PathStepIterator (PathStepIterator other)
  219. : base (other)
  220. {
  221. left = other.left.Clone ();
  222. step = other.step;
  223. if (other.right != null)
  224. right = other.right.Clone ();
  225. if (other.nodeStore != null)
  226. nodeStore = (ArrayList) other.nodeStore.Clone ();
  227. if (other.storedIterators != null)
  228. storedIterators = (SortedList) other.storedIterators.Clone ();
  229. if (other.nextRight != null)
  230. nextRight = other.nextRight.Clone ();
  231. }
  232. public override XPathSequence Clone ()
  233. {
  234. return new PathStepIterator (this);
  235. }
  236. protected override bool MoveNextCore ()
  237. {
  238. if (finished)
  239. return false;
  240. // if (RequireSorting) {
  241. if (step.RequireSorting) {
  242. // Mainly '//' ('/descendant-or-self::node()/')
  243. if (nodeStore == null) {
  244. CollectResults ();
  245. if (nodeStore.Count == 0) {
  246. finished = true;
  247. return false;
  248. }
  249. }
  250. if (nodeStore.Count == Position) {
  251. finished = true;
  252. return false;
  253. }
  254. while (nodeStore.Count > Position) {
  255. if (((XPathNavigator) nodeStore [Position]).ComparePosition (
  256. (XPathNavigator) nodeStore [Position - 1]) == XmlNodeOrder.Same)
  257. nodeStore.RemoveAt (Position);
  258. else
  259. break;
  260. }
  261. return true;
  262. } else { // Sorting not required
  263. if (right == null) { // First time
  264. if (!left.MoveNext ())
  265. return false;
  266. right = step.Next.Evaluate (left);
  267. storedIterators = new SortedList (XPathSequenceComparer.Instance);
  268. }
  269. while (true) {
  270. while (!right.MoveNext ()) {
  271. if (storedIterators.Count > 0) {
  272. int last = storedIterators.Count - 1;
  273. XPathSequence tmpIter = (XPathSequence) storedIterators.GetByIndex (last);
  274. storedIterators.RemoveAt (last);
  275. switch (((XPathNavigator) tmpIter.Current).ComparePosition ((XPathNavigator) right.Current)) {
  276. case XmlNodeOrder.Same:
  277. case XmlNodeOrder.Before:
  278. right = tmpIter;
  279. continue;
  280. default:
  281. right = tmpIter;
  282. break;
  283. }
  284. break;
  285. } else if (nextRight != null) {
  286. right = nextRight;
  287. nextRight = null;
  288. break;
  289. } else if (!left.MoveNext ()) {
  290. finished = true;
  291. return false;
  292. }
  293. else
  294. right = step.Next.Evaluate (left);
  295. }
  296. bool loop = true;
  297. while (loop) {
  298. loop = false;
  299. if (nextRight == null) {
  300. bool noMoreNext = false;
  301. while (nextRight == null || !nextRight.MoveNext ()) {
  302. if(left.MoveNext ())
  303. nextRight = step.Next.Evaluate (left);
  304. else {
  305. noMoreNext = true;
  306. break;
  307. }
  308. }
  309. if (noMoreNext)
  310. nextRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
  311. }
  312. if (nextRight != null) {
  313. switch (((XPathNavigator) right.Current).ComparePosition ((XPathNavigator) nextRight.Current)) {
  314. case XmlNodeOrder.After:
  315. storedIterators.Add (storedIterators.Count, right);
  316. right = nextRight;
  317. nextRight = null;
  318. loop = true;
  319. break;
  320. case XmlNodeOrder.Same:
  321. if (!nextRight.MoveNext ())
  322. nextRight = null;
  323. else {
  324. int last = storedIterators.Count;
  325. if (last > 0) {
  326. storedIterators.Add (last, nextRight);
  327. nextRight = (XPathSequence) storedIterators.GetByIndex (last);
  328. storedIterators.RemoveAt (last);
  329. }
  330. }
  331. loop = true;
  332. break;
  333. }
  334. }
  335. }
  336. return true;
  337. }
  338. }
  339. }
  340. private void CollectResults ()
  341. {
  342. if (nodeStore != null)
  343. return;
  344. nodeStore = new ArrayList ();
  345. while (true) {
  346. while (right == null || !right.MoveNext ()) {
  347. if (!left.MoveNext ()) {
  348. nodeStore.Sort (XPathNavigatorComparer2.Instance);
  349. return;
  350. }
  351. right = step.Next.Evaluate (left);
  352. }
  353. XPathNavigator nav = (XPathNavigator) right.Current;
  354. nodeStore.Add (nav);
  355. }
  356. }
  357. public override XPathItem CurrentCore {
  358. get {
  359. if (Position <= 0) return null;
  360. // if (RequireSorting) {
  361. if (step.RequireSorting) {
  362. return (XPathNavigator) nodeStore [Position - 1];
  363. } else {
  364. return right.Current;
  365. }
  366. }
  367. }
  368. /*
  369. public override bool RequireSorting {
  370. get {
  371. return left.RequireSorting || step.Next.RequireSorting;
  372. }
  373. }
  374. */
  375. public override int Count {
  376. get {
  377. if (nodeStore == null)
  378. return base.Count;
  379. else
  380. return nodeStore.Count;
  381. }
  382. }
  383. internal class XPathSequenceComparer : IComparer
  384. {
  385. public static XPathSequenceComparer Instance = new XPathSequenceComparer ();
  386. private XPathSequenceComparer ()
  387. {
  388. }
  389. public int Compare (object o1, object o2)
  390. {
  391. XPathSequence nav1 = o1 as XPathSequence;
  392. XPathSequence nav2 = o2 as XPathSequence;
  393. if (nav1 == null)
  394. return -1;
  395. if (nav2 == null)
  396. return 1;
  397. switch (((XPathNavigator) nav1.Current).ComparePosition ((XPathNavigator) nav2.Current)) {
  398. case XmlNodeOrder.Same:
  399. return 0;
  400. case XmlNodeOrder.After:
  401. return -1;
  402. default:
  403. return 1;
  404. }
  405. }
  406. }
  407. internal class XPathNavigatorComparer2 : IComparer
  408. {
  409. public static XPathNavigatorComparer2 Instance = new XPathNavigatorComparer2 ();
  410. private XPathNavigatorComparer2 ()
  411. {
  412. }
  413. public int Compare (object o1, object o2)
  414. {
  415. XPathNavigator nav1 = o1 as XPathNavigator;
  416. XPathNavigator nav2 = o2 as XPathNavigator;
  417. if (nav1 == null)
  418. return -1;
  419. if (nav2 == null)
  420. return 1;
  421. switch (nav1.ComparePosition (nav2)) {
  422. case XmlNodeOrder.Same:
  423. return 0;
  424. case XmlNodeOrder.After:
  425. return 1;
  426. default:
  427. return -1;
  428. }
  429. }
  430. }
  431. }
  432. // </copy>
  433. // Filter step iterator
  434. internal class FilteredIterator : XPathSequence
  435. {
  436. XPathSequence left;
  437. PredicateList filter;
  438. public FilteredIterator (XPathSequence iter, FilterStepExpr source)
  439. : base (iter.Context)
  440. {
  441. left = source.Expr.Evaluate (iter);
  442. filter = source.Predicates;
  443. }
  444. private FilteredIterator (FilteredIterator other)
  445. : base (other)
  446. {
  447. left = other.left.Clone ();
  448. filter = other.filter;
  449. }
  450. public override XPathSequence Clone ()
  451. {
  452. return new FilteredIterator (this);
  453. }
  454. protected override bool MoveNextCore ()
  455. {
  456. throw new NotImplementedException ();
  457. }
  458. public override XPathItem CurrentCore {
  459. get { return left.Current; }
  460. }
  461. }
  462. // AxisIterator
  463. internal class AxisIterator : XPathSequence
  464. {
  465. XPathSequence iter;
  466. AxisStepExpr source;
  467. public AxisIterator (XPathSequence iter, AxisStepExpr source)
  468. : base (iter.Context)
  469. {
  470. this.iter = iter;
  471. this.source = source;
  472. }
  473. private AxisIterator (AxisIterator other)
  474. : base (other)
  475. {
  476. iter = other.iter.Clone ();
  477. source = other.source;
  478. }
  479. public override XPathSequence Clone ()
  480. {
  481. return new AxisIterator (this);
  482. }
  483. protected override bool MoveNextCore ()
  484. {
  485. while (iter.MoveNext ()) {
  486. if (source.Matches (iter.Current as XPathNavigator))
  487. return true;
  488. }
  489. return false;
  490. }
  491. public override XPathItem CurrentCore {
  492. get { return iter.Current; }
  493. }
  494. }
  495. internal abstract class NodeIterator : XPathSequence
  496. {
  497. XPathNavigator node;
  498. XPathNavigator current;
  499. public NodeIterator (XPathSequence iter)
  500. : base (iter.Context)
  501. {
  502. // XPathItem item = iter.Context.CurrentItem;
  503. XPathItem item = iter.Current;
  504. node = item as XPathNavigator;
  505. if (node == null)
  506. throw new XmlQueryException (String.Format ("Current item is expected to be a node, but it is {0} ({1}).", item.XmlType.QualifiedName, item.XmlType.TypeCode));
  507. node = node.Clone ();
  508. }
  509. internal NodeIterator (NodeIterator other, bool cloneFlag)
  510. : base (other)
  511. {
  512. node = other.node.Clone ();
  513. }
  514. internal XPathNavigator Node {
  515. get { return node; }
  516. }
  517. protected override bool MoveNextCore ()
  518. {
  519. if (!base.MoveNext ())
  520. return false;
  521. current = null;
  522. return true;
  523. }
  524. public override XPathItem CurrentCore {
  525. get {
  526. if (current == null)
  527. current = node.Clone ();
  528. return current;
  529. }
  530. }
  531. public virtual bool ReverseAxis {
  532. get { return false; }
  533. }
  534. // public override bool RequireSorting {
  535. // get { return ReverseAxis; }
  536. // }
  537. }
  538. // <copy original='System.Xml.XPath/Iterator.cs'>
  539. internal class ParentIterator : NodeIterator
  540. {
  541. public ParentIterator (XPathSequence iter)
  542. : base (iter)
  543. {
  544. }
  545. private ParentIterator (ParentIterator other, bool cloneFlag)
  546. : base (other, true)
  547. {
  548. }
  549. public override XPathSequence Clone ()
  550. {
  551. return new ParentIterator (this, true);
  552. }
  553. protected override bool MoveNextCore ()
  554. {
  555. if (Position == 0 && Node.MoveToParent ())
  556. return true;
  557. return false;
  558. }
  559. public override bool ReverseAxis {
  560. get { return true; }
  561. }
  562. }
  563. internal class ChildIterator : NodeIterator
  564. {
  565. public ChildIterator (XPathSequence iter)
  566. : base (iter)
  567. {
  568. }
  569. private ChildIterator (ChildIterator other, bool cloneFlag)
  570. : base (other, true)
  571. {
  572. }
  573. public override XPathSequence Clone ()
  574. {
  575. return new ChildIterator (this, true);
  576. }
  577. protected override bool MoveNextCore ()
  578. {
  579. if (Position == 0)
  580. return Node.MoveToFirstChild ();
  581. else
  582. return Node.MoveToNext ();
  583. }
  584. }
  585. internal class FollowingSiblingIterator : NodeIterator
  586. {
  587. public FollowingSiblingIterator (XPathSequence iter)
  588. : base (iter)
  589. {
  590. }
  591. private FollowingSiblingIterator (FollowingSiblingIterator other, bool cloneFlag)
  592. : base (other, true)
  593. {
  594. }
  595. public override XPathSequence Clone ()
  596. {
  597. return new FollowingSiblingIterator (this, true);
  598. }
  599. protected override bool MoveNextCore ()
  600. {
  601. return Node.MoveToNext ();
  602. }
  603. }
  604. internal class PrecedingSiblingIterator : NodeIterator
  605. {
  606. bool finished;
  607. bool started;
  608. XPathNavigator startPosition;
  609. public PrecedingSiblingIterator (XPathSequence iter)
  610. : base (iter)
  611. {
  612. startPosition = Node.Clone ();
  613. }
  614. private PrecedingSiblingIterator (PrecedingSiblingIterator other, bool cloneFlag)
  615. : base (other, true)
  616. {
  617. startPosition = other.startPosition;
  618. started = other.started;
  619. finished = other.finished;
  620. }
  621. public override XPathSequence Clone ()
  622. {
  623. return new PrecedingSiblingIterator (this, true);
  624. }
  625. protected override bool MoveNextCore ()
  626. {
  627. if (finished)
  628. return false;
  629. if (!started) {
  630. started = true;
  631. Node.MoveToFirst ();
  632. } else {
  633. Node.MoveToNext ();
  634. }
  635. if (Node.ComparePosition (startPosition) == XmlNodeOrder.Same) {
  636. finished = true;
  637. return false;
  638. }
  639. else
  640. return true;
  641. }
  642. public override bool ReverseAxis {
  643. get { return true; }
  644. }
  645. }
  646. internal class AncestorIterator : NodeIterator
  647. {
  648. bool finished;
  649. ArrayList nodes = new ArrayList ();
  650. public AncestorIterator (XPathSequence iter)
  651. : base (iter)
  652. {
  653. }
  654. private AncestorIterator (AncestorIterator other, bool cloneFlag)
  655. : base (other, true)
  656. {
  657. finished = other.finished;
  658. nodes = other.nodes;
  659. }
  660. public override XPathSequence Clone ()
  661. {
  662. return new AncestorIterator (this, true);
  663. }
  664. protected override bool MoveNextCore ()
  665. {
  666. if (finished)
  667. return false;
  668. if (nodes != null) {
  669. nodes = new ArrayList ();
  670. while (Node.MoveToParent () && Node.NodeType != XPathNodeType.Root)
  671. nodes.Add (Node.Clone ());
  672. nodes.Reverse ();
  673. }
  674. if (nodes.Count >= Position)
  675. return false;
  676. Node.MoveTo (nodes [Position] as XPathNavigator);
  677. return true;
  678. }
  679. public override bool ReverseAxis {
  680. get { return true; }
  681. }
  682. public override int Count {
  683. get {
  684. if (Position == 0)
  685. return base.Count;
  686. return nodes.Count;
  687. }
  688. }
  689. }
  690. internal class AncestorOrSelfIterator : NodeIterator
  691. {
  692. bool finished;
  693. ArrayList nodes = new ArrayList ();
  694. public AncestorOrSelfIterator (XPathSequence iter)
  695. : base (iter)
  696. {
  697. }
  698. private AncestorOrSelfIterator (AncestorOrSelfIterator other, bool cloneFlag)
  699. : base (other, true)
  700. {
  701. finished = other.finished;
  702. nodes = other.nodes;
  703. }
  704. public override XPathSequence Clone ()
  705. {
  706. return new AncestorOrSelfIterator (this, true);
  707. }
  708. protected override bool MoveNextCore ()
  709. {
  710. if (finished)
  711. return false;
  712. if (nodes != null) {
  713. nodes = new ArrayList ();
  714. do {
  715. nodes.Add (Node.Clone ());
  716. } while (Node.MoveToParent () && Node.NodeType != XPathNodeType.Root);
  717. nodes.Reverse ();
  718. }
  719. if (nodes.Count >= Position)
  720. return false;
  721. Node.MoveTo (nodes [Position] as XPathNavigator);
  722. return true;
  723. }
  724. public override bool ReverseAxis {
  725. get { return true; }
  726. }
  727. public override int Count {
  728. get {
  729. if (Position == 0)
  730. return base.Count;
  731. return nodes.Count;
  732. }
  733. }
  734. }
  735. internal class DescendantIterator : NodeIterator
  736. {
  737. private int depth;
  738. private bool finished;
  739. public DescendantIterator (XPathSequence iter)
  740. : base (iter)
  741. {
  742. }
  743. private DescendantIterator (DescendantIterator other, bool cloneFlag)
  744. : base (other, true)
  745. {
  746. finished = other.finished;
  747. depth = other.depth;
  748. }
  749. public override XPathSequence Clone ()
  750. {
  751. return new DescendantIterator (this, true);
  752. }
  753. protected override bool MoveNextCore ()
  754. {
  755. if (finished)
  756. return false;
  757. if (Node.MoveToFirstChild ()) {
  758. depth ++;
  759. return true;
  760. }
  761. while (depth != 0) {
  762. if (Node.MoveToNext ())
  763. return true;
  764. if (!Node.MoveToParent ()) // should NEVER fail!
  765. throw new XPathException ("There seems some bugs on the XPathNavigator implementation class.");
  766. depth --;
  767. }
  768. finished = true;
  769. return false;
  770. }
  771. }
  772. internal class DescendantOrSelfIterator : NodeIterator
  773. {
  774. protected int depth;
  775. private bool finished;
  776. public DescendantOrSelfIterator (XPathSequence iter)
  777. : base (iter)
  778. {
  779. }
  780. protected DescendantOrSelfIterator (DescendantOrSelfIterator other, bool cloneFlag)
  781. : base (other, true)
  782. {
  783. depth = other.depth;
  784. finished = other.finished;
  785. }
  786. public override XPathSequence Clone ()
  787. {
  788. return new DescendantOrSelfIterator (this, true);
  789. }
  790. protected override bool MoveNextCore ()
  791. {
  792. if (finished)
  793. return false;
  794. if (Position == 0)
  795. return true; // Self
  796. if (Node.MoveToFirstChild ()) {
  797. depth ++;
  798. return true;
  799. }
  800. while (depth != 0) {
  801. if (Node.MoveToNext ())
  802. return true;
  803. if (!Node.MoveToParent ()) // should NEVER fail!
  804. throw new XPathException ("There seems some bugs on the XPathNavigator implementation class.");
  805. depth --;
  806. }
  807. finished = true;
  808. return false;
  809. }
  810. }
  811. internal class FollowingIterator : NodeIterator
  812. {
  813. private bool finished;
  814. public FollowingIterator (XPathSequence iter)
  815. : base (iter)
  816. {
  817. }
  818. protected FollowingIterator (FollowingIterator other, bool cloneFlag)
  819. : base (other, true)
  820. {
  821. finished = other.finished;
  822. }
  823. public override XPathSequence Clone ()
  824. {
  825. return new FollowingIterator (this, true);
  826. }
  827. protected override bool MoveNextCore ()
  828. {
  829. if (finished)
  830. return false;
  831. if (Position == 0) {
  832. // At first, it should not iterate children.
  833. if (Node.MoveToNext ())
  834. return true;
  835. else {
  836. while (Node.MoveToParent ())
  837. if (Node.MoveToNext ())
  838. return true;
  839. }
  840. } else {
  841. if (Node.MoveToFirstChild ())
  842. return true;
  843. do {
  844. if (Node.MoveToNext ())
  845. return true;
  846. } while (Node.MoveToParent ());
  847. }
  848. finished = true;
  849. return false;
  850. }
  851. }
  852. internal class PrecedingIterator : NodeIterator
  853. {
  854. bool finished;
  855. bool started;
  856. XPathNavigator startPosition;
  857. public PrecedingIterator (XPathSequence iter)
  858. : base (iter)
  859. {
  860. startPosition = Node.Clone ();
  861. }
  862. private PrecedingIterator (PrecedingIterator other, bool cloneFlag)
  863. : base (other, true)
  864. {
  865. startPosition = other.startPosition;
  866. started = other.started;
  867. finished = other.finished;
  868. }
  869. public override XPathSequence Clone ()
  870. {
  871. return new PrecedingIterator (this, true);
  872. }
  873. protected override bool MoveNextCore ()
  874. {
  875. if (finished)
  876. return false;
  877. if (!started) {
  878. started = true;
  879. Node.MoveToRoot ();
  880. }
  881. bool loop = true;
  882. while (loop) {
  883. while (!Node.MoveToFirstChild ()) {
  884. while (!Node.MoveToNext ()) {
  885. if (!Node.MoveToParent ()) { // Should not finish, at least before startPosition.
  886. finished = true;
  887. return false;
  888. }
  889. }
  890. break;
  891. }
  892. if (Node.IsDescendant (startPosition))
  893. continue;
  894. loop = false;
  895. break;
  896. }
  897. if (Node.ComparePosition (startPosition) != XmlNodeOrder.Before) {
  898. // Note that if _nav contains only 1 node, it won't be Same.
  899. finished = true;
  900. return false;
  901. }
  902. else
  903. return true;
  904. }
  905. public override bool ReverseAxis {
  906. get { return true; }
  907. }
  908. }
  909. internal class NamespaceIterator : NodeIterator
  910. {
  911. public NamespaceIterator (XPathSequence iter)
  912. : base (iter)
  913. {
  914. }
  915. private NamespaceIterator (NamespaceIterator other, bool cloneFlag)
  916. : base (other, true)
  917. {
  918. }
  919. public override XPathSequence Clone ()
  920. {
  921. return new NamespaceIterator (this, true);
  922. }
  923. protected override bool MoveNextCore ()
  924. {
  925. if (Position == 0) {
  926. if (Node.MoveToFirstNamespace ())
  927. return true;
  928. }
  929. else if (Node.MoveToNextNamespace ())
  930. return true;
  931. return false;
  932. }
  933. public override bool ReverseAxis { get { return true; } }
  934. }
  935. internal class AttributeIterator : NodeIterator
  936. {
  937. public AttributeIterator (XPathSequence iter)
  938. : base (iter)
  939. {
  940. }
  941. private AttributeIterator (AttributeIterator other, bool cloneFlag)
  942. : base (other, true)
  943. {
  944. }
  945. public override XPathSequence Clone ()
  946. {
  947. return new AttributeIterator (this, true);
  948. }
  949. protected override bool MoveNextCore ()
  950. {
  951. if (Position == 0) {
  952. if (Node.MoveToFirstAttribute ())
  953. return true;
  954. }
  955. else if (Node.MoveToNextAttribute ())
  956. return true;
  957. return false;
  958. }
  959. }
  960. // </copy>
  961. internal class ExprSequenceIterator : XPathSequence
  962. {
  963. XPathSequence contextSequence;
  964. XPathSequence iter;
  965. ExprSequence expr;
  966. int currentExprIndex;
  967. public ExprSequenceIterator (XPathSequence iter, ExprSequence expr)
  968. : base (iter.Context)
  969. {
  970. contextSequence = iter;
  971. this.expr = expr;
  972. }
  973. private ExprSequenceIterator (ExprSequenceIterator other)
  974. : base (other)
  975. {
  976. if (other.iter != null)
  977. iter = other.iter.Clone ();
  978. expr = other.expr;
  979. currentExprIndex = other.currentExprIndex;
  980. }
  981. public override XPathSequence Clone ()
  982. {
  983. return new ExprSequenceIterator (this);
  984. }
  985. protected override bool MoveNextCore ()
  986. {
  987. if (iter != null && iter.MoveNext ())
  988. return true;
  989. while (currentExprIndex < expr.Count) {
  990. iter = expr [currentExprIndex++].Evaluate (contextSequence);
  991. if (iter.MoveNext ())
  992. return true;
  993. }
  994. return false;
  995. }
  996. public override XPathItem CurrentCore {
  997. get { return iter.Current; }
  998. }
  999. }
  1000. internal class FLWORIterator : XPathSequence
  1001. {
  1002. XPathSequence contextSequence;
  1003. FLWORExpr expr;
  1004. public FLWORIterator (XPathSequence iter, FLWORExpr expr)
  1005. : base (iter.Context)
  1006. {
  1007. this.contextSequence = iter;
  1008. this.expr = expr;
  1009. }
  1010. private FLWORIterator (FLWORIterator other)
  1011. : base (other)
  1012. {
  1013. contextSequence = other.contextSequence;
  1014. expr = other.expr;
  1015. throw new NotImplementedException ();
  1016. }
  1017. public override XPathSequence Clone ()
  1018. {
  1019. return new FLWORIterator (this);
  1020. }
  1021. protected override bool MoveNextCore ()
  1022. {
  1023. throw new NotImplementedException ();
  1024. }
  1025. public override XPathItem CurrentCore {
  1026. get { throw new NotImplementedException (); }
  1027. }
  1028. }
  1029. internal class AtomizingIterator : XPathSequence
  1030. {
  1031. XPathSequence iter;
  1032. public AtomizingIterator (XPathSequence iter)
  1033. : base (iter.Context)
  1034. {
  1035. this.iter = iter;
  1036. }
  1037. private AtomizingIterator (AtomizingIterator other)
  1038. : base (other)
  1039. {
  1040. iter = other.iter.Clone ();
  1041. }
  1042. public override XPathSequence Clone ()
  1043. {
  1044. return new AtomizingIterator (this);
  1045. }
  1046. protected override bool MoveNextCore ()
  1047. {
  1048. return iter.MoveNext ();
  1049. }
  1050. public override XPathItem CurrentCore {
  1051. get {
  1052. XPathNavigator nav = iter.Current as XPathNavigator;
  1053. if (nav == null)
  1054. return (XPathAtomicValue) iter.Current;
  1055. if (nav.SchemaInfo != null)
  1056. return new XPathAtomicValue (
  1057. nav.TypedValue,
  1058. nav.SchemaInfo.SchemaType);
  1059. else
  1060. return new XPathAtomicValue (nav.Value, null);
  1061. }
  1062. }
  1063. }
  1064. internal class ConvertingIterator : XPathSequence
  1065. {
  1066. XPathSequence iter;
  1067. SequenceType type;
  1068. public ConvertingIterator (XPathSequence iter, SequenceType type)
  1069. : base (iter.Context)
  1070. {
  1071. this.iter = iter;
  1072. type = type;
  1073. }
  1074. private ConvertingIterator (ConvertingIterator other)
  1075. : base (other)
  1076. {
  1077. iter = other.iter.Clone ();
  1078. type = other.type;
  1079. }
  1080. public override XPathSequence Clone ()
  1081. {
  1082. return new ConvertingIterator (this);
  1083. }
  1084. protected override bool MoveNextCore ()
  1085. {
  1086. return iter.MoveNext ();
  1087. }
  1088. public override XPathItem CurrentCore {
  1089. get { return type.Convert (iter.Current); }
  1090. }
  1091. }
  1092. internal class TracingIterator : XPathSequence
  1093. {
  1094. XPathSequence iter;
  1095. string format;
  1096. public TracingIterator (XPathSequence iter, string format)
  1097. : base (iter.Context)
  1098. {
  1099. this.iter = iter;
  1100. this.format = format;
  1101. }
  1102. private TracingIterator (TracingIterator other)
  1103. : base (other)
  1104. {
  1105. iter = other.iter.Clone ();
  1106. format = other.format;
  1107. }
  1108. public override XPathSequence Clone ()
  1109. {
  1110. return new TracingIterator (this);
  1111. }
  1112. protected override bool MoveNextCore ()
  1113. {
  1114. if (!iter.MoveNext ())
  1115. return false;
  1116. // FIXME: use OnMessageEvent
  1117. // Context.ErrorOutput.Write (format, iter.Current.TypedValue);
  1118. throw new NotImplementedException ();
  1119. return true;
  1120. }
  1121. public override XPathItem CurrentCore {
  1122. get { return iter.Current; }
  1123. }
  1124. }
  1125. internal class ListIterator : XPathSequence
  1126. {
  1127. IList list;
  1128. public ListIterator (XPathSequence iter, IList list)
  1129. : base (iter.Context)
  1130. {
  1131. if (list is ICloneable)
  1132. this.list = list;
  1133. else
  1134. throw new InvalidOperationException (String.Format ("XQuery internal error: target list is not cloneable. List is {0}.", list != null ? list.GetType ().ToString () : "null argument"));
  1135. }
  1136. private ListIterator (ListIterator other)
  1137. : base (other)
  1138. {
  1139. this.list = (IList) ((ICloneable) other.list).Clone ();
  1140. }
  1141. public override XPathSequence Clone ()
  1142. {
  1143. return new ListIterator (this);
  1144. }
  1145. protected override bool MoveNextCore ()
  1146. {
  1147. return (Position < list.Count);
  1148. }
  1149. public override XPathItem CurrentCore {
  1150. get { return (XPathItem) list [Position - 1]; }
  1151. }
  1152. }
  1153. }
  1154. #endif