Iterator.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. //
  2. // System.Xml.XPath.BaseIterator
  3. //
  4. // Author:
  5. // Piers Haken ([email protected])
  6. //
  7. // (C) 2002 Piers Haken
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Xml;
  12. using System.Xml.XPath;
  13. using System.Xml.Xsl;
  14. namespace System.Xml.XPath
  15. {
  16. internal abstract class BaseIterator : XPathNodeIterator
  17. {
  18. private XsltContext _context;
  19. internal BaseIterator (BaseIterator other)
  20. {
  21. _context = other._context;
  22. }
  23. internal BaseIterator (XsltContext context)
  24. {
  25. _context = context;
  26. }
  27. public XsltContext Context { get { return _context; } }
  28. public override string ToString ()
  29. {
  30. return Current.NodeType.ToString () + "[" + CurrentPosition + "] : " + Current.Name + " = " + Current.Value;
  31. }
  32. }
  33. internal class MergedIterator : BaseIterator
  34. {
  35. protected ArrayList _iters = new ArrayList ();
  36. protected int _pos;
  37. protected int _index;
  38. public MergedIterator (BaseIterator iter ) : base (iter) {}
  39. protected MergedIterator (MergedIterator other) : base (other)
  40. {
  41. foreach (object obj in other._iters)
  42. _iters.Add (obj);
  43. _pos = other._pos;
  44. _index = other._index;
  45. }
  46. public override XPathNodeIterator Clone () { return new MergedIterator (this); }
  47. public void Add (BaseIterator iter)
  48. {
  49. _iters.Add (iter);
  50. }
  51. public override bool MoveNext ()
  52. {
  53. while (_index < _iters.Count)
  54. {
  55. BaseIterator iter = (BaseIterator) _iters [_index];
  56. if (iter.MoveNext ())
  57. {
  58. _pos ++;
  59. return true;
  60. }
  61. _index ++;
  62. }
  63. return false;
  64. }
  65. public override XPathNavigator Current
  66. {
  67. get
  68. {
  69. if (_index >= _iters.Count)
  70. return null;
  71. BaseIterator iter = (BaseIterator) _iters [_index];
  72. return iter.Current;
  73. }
  74. }
  75. public override int CurrentPosition { get { return _pos; }}
  76. }
  77. internal abstract class SimpleIterator : BaseIterator
  78. {
  79. protected XPathNavigator _nav;
  80. protected int _pos;
  81. public SimpleIterator (BaseIterator iter) : base (iter)
  82. {
  83. _nav = iter.Current.Clone ();
  84. }
  85. protected SimpleIterator (SimpleIterator other) : base (other)
  86. {
  87. _nav = other._nav.Clone ();
  88. _pos = other._pos;
  89. }
  90. public SimpleIterator (XPathNavigator nav, XsltContext context) : base (context)
  91. {
  92. _nav = nav.Clone ();
  93. }
  94. public override XPathNavigator Current { get { return _nav; }}
  95. public override int CurrentPosition { get { return _pos; }}
  96. }
  97. internal class SelfIterator : SimpleIterator
  98. {
  99. public SelfIterator (BaseIterator iter) : base (iter) {}
  100. public SelfIterator (XPathNavigator nav, XsltContext context) : base (nav, context) {}
  101. protected SelfIterator (SimpleIterator other) : base (other) {}
  102. public override XPathNodeIterator Clone () { return new SelfIterator (this); }
  103. public override bool MoveNext ()
  104. {
  105. if (_pos == 0)
  106. {
  107. _pos = 1;
  108. return true;
  109. }
  110. return false;
  111. }
  112. }
  113. internal class ParentIterator : SimpleIterator
  114. {
  115. public ParentIterator (BaseIterator iter) : base (iter) {}
  116. protected ParentIterator (SimpleIterator other) : base (other) {}
  117. public override XPathNodeIterator Clone () { return new ParentIterator (this); }
  118. public override bool MoveNext ()
  119. {
  120. if (_pos == 0 && _nav.MoveToParent ())
  121. {
  122. _pos = 1;
  123. return true;
  124. }
  125. return false;
  126. }
  127. }
  128. internal class ChildIterator : SimpleIterator
  129. {
  130. public ChildIterator (BaseIterator iter) : base (iter) {}
  131. protected ChildIterator (SimpleIterator other) : base (other) {}
  132. public override XPathNodeIterator Clone () { return new ChildIterator (this); }
  133. public override bool MoveNext ()
  134. {
  135. bool fSuccess = (_pos == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
  136. if (fSuccess)
  137. _pos ++;
  138. return fSuccess;
  139. }
  140. }
  141. internal class FollowingSiblingIterator : SimpleIterator
  142. {
  143. public FollowingSiblingIterator (BaseIterator iter) : base (iter) {}
  144. protected FollowingSiblingIterator (SimpleIterator other) : base (other) {}
  145. public override XPathNodeIterator Clone () { return new FollowingSiblingIterator (this); }
  146. public override bool MoveNext ()
  147. {
  148. if (_nav.MoveToNext ())
  149. {
  150. _pos ++;
  151. return true;
  152. }
  153. return false;
  154. }
  155. }
  156. internal class PrecedingSiblingIterator : SimpleIterator
  157. {
  158. public PrecedingSiblingIterator (BaseIterator iter) : base (iter) {}
  159. protected PrecedingSiblingIterator (SimpleIterator other) : base (other) {}
  160. public override XPathNodeIterator Clone () { return new PrecedingSiblingIterator (this); }
  161. public override bool MoveNext ()
  162. {
  163. if (_nav.MoveToPrevious ())
  164. {
  165. _pos ++;
  166. return true;
  167. }
  168. return false;
  169. }
  170. }
  171. internal class AncestorIterator : SimpleIterator
  172. {
  173. public AncestorIterator (BaseIterator iter) : base (iter) {}
  174. protected AncestorIterator (SimpleIterator other) : base (other) {}
  175. public override XPathNodeIterator Clone () { return new AncestorIterator (this); }
  176. public override bool MoveNext ()
  177. {
  178. if (_nav.MoveToParent ())
  179. {
  180. _pos ++;
  181. return true;
  182. }
  183. return false;
  184. }
  185. }
  186. internal class AncestorOrSelfIterator : MergedIterator
  187. {
  188. public AncestorOrSelfIterator (BaseIterator iter) : base (iter)
  189. {
  190. Add (new SelfIterator (iter));
  191. Add (new AncestorIterator (iter));
  192. }
  193. protected AncestorOrSelfIterator (MergedIterator other) : base (other) {}
  194. public override XPathNodeIterator Clone () { return new AncestorOrSelfIterator (this); }
  195. }
  196. internal class DescendantIterator : SimpleIterator
  197. {
  198. protected int _depth;
  199. public DescendantIterator (BaseIterator iter) : base (iter) {}
  200. protected DescendantIterator (SimpleIterator other) : base (other) {}
  201. public override XPathNodeIterator Clone () { return new DescendantIterator (this); }
  202. [MonoTODO]
  203. public override bool MoveNext ()
  204. {
  205. if (_nav.MoveToFirstChild ())
  206. {
  207. _depth ++;
  208. _pos ++;
  209. return true;
  210. }
  211. while (_depth != 0)
  212. {
  213. if (_nav.MoveToNext ())
  214. {
  215. _pos ++;
  216. return true;
  217. }
  218. if (!_nav.MoveToParent ()) // should NEVER fail!
  219. throw new Exception ("unexpected depth"); // TODO: better message
  220. _depth --;
  221. }
  222. return false;
  223. }
  224. }
  225. internal class DescendantOrSelfIterator : MergedIterator
  226. {
  227. public DescendantOrSelfIterator (BaseIterator iter) : base (iter)
  228. {
  229. Add (new SelfIterator (iter));
  230. Add (new DescendantIterator (iter));
  231. }
  232. protected DescendantOrSelfIterator (MergedIterator other) : base (other) {}
  233. public override XPathNodeIterator Clone () { return new DescendantOrSelfIterator (this); }
  234. }
  235. internal class FollowingIterator : SimpleIterator
  236. {
  237. public FollowingIterator (BaseIterator iter) : base (iter) {}
  238. protected FollowingIterator (SimpleIterator other) : base (other) {}
  239. public override XPathNodeIterator Clone () { return new FollowingIterator (this); }
  240. public override bool MoveNext ()
  241. {
  242. if (_pos == 0)
  243. {
  244. if (_nav.MoveToNext ())
  245. {
  246. _pos ++;
  247. return true;
  248. }
  249. }
  250. else
  251. {
  252. if (_nav.MoveToFirstChild ())
  253. {
  254. _pos ++;
  255. return true;
  256. }
  257. do
  258. {
  259. if (_nav.MoveToNext ())
  260. {
  261. _pos ++;
  262. return true;
  263. }
  264. }
  265. while (_nav.MoveToParent ());
  266. }
  267. return false;
  268. }
  269. }
  270. internal class PrecedingIterator : SimpleIterator
  271. {
  272. public PrecedingIterator (BaseIterator iter) : base (iter) {}
  273. protected PrecedingIterator (SimpleIterator other) : base (other) {}
  274. public override XPathNodeIterator Clone () { return new PrecedingIterator (this); }
  275. public override bool MoveNext ()
  276. {
  277. if (_pos == 0)
  278. {
  279. if (_nav.MoveToPrevious ())
  280. {
  281. _pos ++;
  282. return true;
  283. }
  284. }
  285. else
  286. {
  287. if (_nav.MoveToFirstChild ())
  288. {
  289. while (_nav.MoveToNext ())
  290. ;
  291. _pos ++;
  292. return true;
  293. }
  294. do
  295. {
  296. if (_nav.MoveToPrevious ())
  297. {
  298. _pos ++;
  299. return true;
  300. }
  301. }
  302. while (_nav.MoveToParent ());
  303. }
  304. return false;
  305. }
  306. }
  307. internal class NamespaceIterator : SimpleIterator
  308. {
  309. public NamespaceIterator (BaseIterator iter) : base (iter) {}
  310. protected NamespaceIterator (SimpleIterator other) : base (other) {}
  311. public override XPathNodeIterator Clone () { return new NamespaceIterator (this); }
  312. public override bool MoveNext ()
  313. {
  314. if (_pos == 0)
  315. {
  316. if (_nav.MoveToFirstNamespace ())
  317. {
  318. _pos ++;
  319. return true;
  320. }
  321. }
  322. else if (_nav.MoveToNextNamespace ())
  323. {
  324. _pos ++;
  325. return true;
  326. }
  327. return false;
  328. }
  329. }
  330. internal class AttributeIterator : SimpleIterator
  331. {
  332. public AttributeIterator (BaseIterator iter) : base (iter) {}
  333. protected AttributeIterator (SimpleIterator other) : base (other) {}
  334. public override XPathNodeIterator Clone () { return new AttributeIterator (this); }
  335. public override bool MoveNext ()
  336. {
  337. if (_pos == 0)
  338. {
  339. if (_nav.MoveToFirstAttribute ())
  340. {
  341. _pos += 1;
  342. return true;
  343. }
  344. }
  345. else if (_nav.MoveToNextAttribute ())
  346. {
  347. _pos ++;
  348. return true;
  349. }
  350. return false;
  351. }
  352. }
  353. internal class AxisIterator : BaseIterator
  354. {
  355. protected BaseIterator _iter;
  356. protected NodeTest _test;
  357. protected int _pos;
  358. public AxisIterator (BaseIterator iter, NodeTest test) : base (iter)
  359. {
  360. _iter = iter;
  361. _test = test;
  362. }
  363. protected AxisIterator (AxisIterator other) : base (other)
  364. {
  365. _iter = (BaseIterator) other._iter.Clone ();
  366. _test = other._test;
  367. _pos = other._pos;
  368. }
  369. public override XPathNodeIterator Clone () { return new AxisIterator (this); }
  370. public override bool MoveNext ()
  371. {
  372. while (_iter.MoveNext ())
  373. {
  374. if (_test.Match (Context, Current))
  375. {
  376. _pos ++;
  377. return true;
  378. }
  379. }
  380. return false;
  381. }
  382. public override XPathNavigator Current { get { return _iter.Current; }}
  383. public override int CurrentPosition { get { return _pos; }}
  384. }
  385. internal class SlashIterator : BaseIterator
  386. {
  387. protected BaseIterator _iterLeft;
  388. protected BaseIterator _iterRight;
  389. protected Expression _expr;
  390. protected int _pos;
  391. public SlashIterator (BaseIterator iter, Expression expr) : base (iter)
  392. {
  393. _iterLeft = iter;
  394. _expr = expr;
  395. }
  396. protected SlashIterator (SlashIterator other) : base (other)
  397. {
  398. _iterLeft = (BaseIterator) other._iterLeft.Clone ();
  399. _iterRight = (BaseIterator) other._iterRight.Clone ();
  400. _expr = other._expr;
  401. _pos = other._pos;
  402. }
  403. public override XPathNodeIterator Clone () { return new SlashIterator (this); }
  404. public override bool MoveNext ()
  405. {
  406. while (_iterRight == null || !_iterRight.MoveNext ())
  407. {
  408. if (!_iterLeft.MoveNext ())
  409. return false;
  410. _iterRight = _expr.EvaluateNodeSet (_iterLeft);
  411. }
  412. _pos ++;
  413. return true;
  414. }
  415. public override XPathNavigator Current { get { return _iterRight.Current; }}
  416. public override int CurrentPosition { get { return _pos; }}
  417. }
  418. internal class PredicateIterator : BaseIterator
  419. {
  420. protected BaseIterator _iter;
  421. protected Expression [] _preds;
  422. protected int _pos;
  423. public PredicateIterator (BaseIterator iter, Expression [] preds) : base (iter)
  424. {
  425. _iter = iter;
  426. _preds = preds;
  427. }
  428. protected PredicateIterator (PredicateIterator other) : base (other)
  429. {
  430. _iter = (BaseIterator) other._iter.Clone ();
  431. _preds = other._preds;
  432. _pos = other._pos;
  433. }
  434. public override XPathNodeIterator Clone () { return new PredicateIterator (this); }
  435. public override bool MoveNext ()
  436. {
  437. while (_iter.MoveNext ())
  438. {
  439. bool fTrue = true;
  440. foreach (Expression pred in _preds)
  441. {
  442. object result = pred.Evaluate ((BaseIterator) _iter.Clone ());
  443. if (result is double)
  444. {
  445. if ((double) result != _iter.CurrentPosition)
  446. {
  447. fTrue = false;
  448. break;
  449. }
  450. }
  451. else if (!XPathFunctions.ToBoolean (result))
  452. {
  453. fTrue = false;
  454. break;
  455. }
  456. }
  457. if (fTrue)
  458. return true;
  459. }
  460. return false;
  461. }
  462. public override XPathNavigator Current { get { return _iter.Current; }}
  463. public override int CurrentPosition { get { return _pos; }}
  464. }
  465. internal class ArrayListIterator : BaseIterator
  466. {
  467. protected ArrayList _rgNodes;
  468. protected int _pos;
  469. public ArrayListIterator (BaseIterator iter, ArrayList rgNodes) : base (iter)
  470. {
  471. _rgNodes = rgNodes;
  472. }
  473. protected ArrayListIterator (ArrayListIterator other) : base (other)
  474. {
  475. _rgNodes = other._rgNodes;
  476. _pos = other._pos;
  477. }
  478. public override XPathNodeIterator Clone () { return new ArrayListIterator (this); }
  479. public override bool MoveNext ()
  480. {
  481. if (_pos >= _rgNodes.Count)
  482. return false;
  483. _pos++;
  484. return true;
  485. }
  486. public override XPathNavigator Current { get { return (XPathNavigator) _rgNodes [_pos - 1]; }}
  487. public override int CurrentPosition { get { return _pos; }}
  488. }
  489. internal class UnionIterator : BaseIterator
  490. {
  491. protected ArrayList _rgNodes;
  492. protected BaseIterator _left, _right;
  493. protected int _pos;
  494. public UnionIterator (BaseIterator iter, BaseIterator left, BaseIterator right) : base (iter)
  495. {
  496. _rgNodes = new ArrayList ();
  497. _left = left;
  498. _right = right;
  499. }
  500. protected UnionIterator (UnionIterator other) : base (other)
  501. {
  502. _rgNodes = (ArrayList) other._rgNodes.Clone ();
  503. _left = other._left;
  504. _right = other._right;
  505. _pos = other._pos;
  506. }
  507. public override XPathNodeIterator Clone () { return new UnionIterator (this); }
  508. public override bool MoveNext ()
  509. {
  510. if (_left.MoveNext ())
  511. {
  512. _rgNodes.Add (_left.Current.Clone ());
  513. _pos ++;
  514. return true;
  515. }
  516. while (_right.MoveNext ())
  517. {
  518. XPathNavigator navRight = _right.Current;
  519. bool fFound = false;
  520. foreach (XPathNavigator navLeft in _rgNodes)
  521. {
  522. if (navLeft.IsSamePosition (navRight))
  523. {
  524. fFound = true;
  525. break;
  526. }
  527. }
  528. if (!fFound)
  529. {
  530. _pos ++;
  531. return true;
  532. }
  533. }
  534. return false;
  535. }
  536. public override XPathNavigator Current
  537. {
  538. get
  539. {
  540. if (_pos < _rgNodes.Count)
  541. throw new Exception ("bug in UnionOperator"); // TODO: better exception
  542. if (_pos == _rgNodes.Count)
  543. return _left.Current;
  544. else
  545. return _right.Current;
  546. }
  547. }
  548. public override int CurrentPosition { get { return _pos; }}
  549. }
  550. }