Iterator.cs 13 KB

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