1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 namespace System.ServiceModel.Dispatcher 5 { 6 using System.Runtime; 7 using System.Xml; 8 using System.Xml.XPath; 9 10 #if NO 11 // 12 // A message is just one more source of Xml data. To filter a message, we create a navigator over it that 13 // surfaces its contained Xml to the filter engine. 14 // In M5.1, we navigate messages by first writing them into a message document. This turns the message into an 15 // Xml DOM. we then get a navigator from the DOM. 16 // In M5.2, we'll navigate messages without requiring this step. 17 // 18 internal class MessageNavigator : GenericSeekableNavigator 19 { 20 StringBuilder builder; 21 int headerCollectionVersion; 22 bool loaded; 23 bool navigatesBody; 24 MessageNavigator(MessageNavigator nav)25 internal MessageNavigator(MessageNavigator nav) 26 : base(nav) 27 { 28 this.headerCollectionVersion = nav.headerCollectionVersion; 29 this.loaded = nav.loaded; 30 this.navigatesBody = nav.navigatesBody; 31 } 32 MessageNavigator(Message message, bool navigateBody)33 internal MessageNavigator(Message message, bool navigateBody) 34 : base() 35 { 36 this.navigatesBody = navigateBody; 37 this.Load(message, this.navigatesBody); 38 } 39 40 internal bool IsLoaded 41 { 42 get 43 { 44 return this.loaded; 45 } 46 } 47 48 internal bool NavigatesBody 49 { 50 get 51 { 52 return this.navigatesBody; 53 } 54 } 55 Clear()56 internal override void Clear() 57 { 58 base.Clear(); 59 this.loaded = false; 60 this.navigatesBody = false; 61 } 62 Clone()63 public override XPathNavigator Clone() 64 { 65 return new MessageNavigator(this); 66 } 67 Ensure(Message message, bool navigateBody)68 internal MessageNavigator Ensure(Message message, bool navigateBody) 69 { 70 // Rebuild the navigator if: 71 // If this navigator does not navigate on bodies and now we need to (or vice versa) 72 // Or the header collection changed under us 73 if (this.navigatesBody != navigateBody || message.Headers.CollectionVersion != this.headerCollectionVersion) 74 { 75 this.Load(message, navigateBody); 76 } 77 else 78 { 79 this.MoveToRoot(); 80 } 81 82 return this; 83 } 84 85 // To load a message into a message document, we write the message into a buffer and then let XPathDocument 86 // load that buffer Load(Message message, bool navigatesBody)87 internal void Load(Message message, bool navigatesBody) 88 { 89 if (null == this.builder) 90 { 91 this.builder = new StringBuilder(1024); 92 } 93 94 StringWriter stringWriter = new StringWriter(this.builder); 95 XmlWriter writer = new XmlTextWriter(stringWriter); 96 97 message.WriteMessage(writer, navigatesBody); 98 writer.Close(); 99 100 StringReader reader = new StringReader(this.builder.ToString()); 101 XPathDocument messageDoc = new XPathDocument(reader); 102 reader.Close(); 103 this.builder.Length = 0; 104 105 this.Init(messageDoc.CreateNavigator()); 106 this.loaded = true; 107 this.navigatesBody = navigatesBody; 108 this.headerCollectionVersion = message.Headers.CollectionVersion; 109 } 110 } 111 #endif 112 113 // To prevent XPaths from running forever etc, users can specify limits on: 114 // the # of nodes a filter or filter table should inspect 115 // 116 // This file contains navigators that impose these limits 117 118 internal interface INodeCounter 119 { 120 int CounterMarker { get; set; } 121 int MaxCounter { set; } ElapsedCount(int marker)122 int ElapsedCount(int marker); Increase()123 void Increase(); IncreaseBy(int count)124 void IncreaseBy(int count); 125 } 126 127 internal class DummyNodeCounter : INodeCounter 128 { 129 internal static DummyNodeCounter Dummy = new DummyNodeCounter(); 130 public int CounterMarker 131 { 132 get { return 0; } 133 set { } 134 } 135 136 public int MaxCounter 137 { 138 set { } 139 } 140 ElapsedCount(int marker)141 public int ElapsedCount(int marker) { return 0; } 142 Increase()143 public void Increase() { } IncreaseBy(int count)144 public void IncreaseBy(int count) { } 145 } 146 147 /// <summary> 148 /// Seekable navigators that wrap other navigators and doesn't exceed node counting limits 149 /// </summary> 150 internal class SafeSeekableNavigator : SeekableXPathNavigator, INodeCounter 151 { 152 SeekableXPathNavigator navigator; 153 SafeSeekableNavigator counter; 154 int nodeCount; 155 int nodeCountMax; 156 SafeSeekableNavigator(SafeSeekableNavigator nav)157 internal SafeSeekableNavigator(SafeSeekableNavigator nav) 158 { 159 this.navigator = (SeekableXPathNavigator)nav.navigator.Clone(); 160 this.counter = nav.counter; 161 } 162 SafeSeekableNavigator(SeekableXPathNavigator navigator, int nodeCountMax)163 internal SafeSeekableNavigator(SeekableXPathNavigator navigator, int nodeCountMax) 164 { 165 this.navigator = navigator; 166 this.counter = this; 167 this.nodeCount = nodeCountMax; 168 this.nodeCountMax = nodeCountMax; 169 } 170 171 public override string BaseURI 172 { 173 get 174 { 175 return this.navigator.BaseURI; 176 } 177 } 178 179 public int CounterMarker 180 { 181 get 182 { 183 return this.counter.nodeCount; 184 } 185 set 186 { 187 this.counter.nodeCount = value; 188 } 189 } 190 191 public int MaxCounter 192 { 193 set 194 { 195 this.counter.nodeCountMax = value; 196 } 197 } 198 199 /// <summary> 200 /// Setting the current position moves this navigator to the location specified by the given position 201 /// </summary> 202 public override long CurrentPosition 203 { 204 get 205 { 206 return this.navigator.CurrentPosition; 207 } 208 set 209 { 210 this.navigator.CurrentPosition = value; 211 } 212 } 213 214 public override bool HasAttributes 215 { 216 get 217 { 218 return this.navigator.HasAttributes; 219 } 220 } 221 222 public override bool HasChildren 223 { 224 get 225 { 226 return this.navigator.HasChildren; 227 } 228 } 229 230 public override bool IsEmptyElement 231 { 232 get 233 { 234 return this.navigator.IsEmptyElement; 235 } 236 } 237 238 public override string LocalName 239 { 240 get 241 { 242 return this.navigator.LocalName; 243 } 244 } 245 246 public override string Name 247 { 248 get 249 { 250 return this.navigator.Name; 251 } 252 } 253 254 public override string NamespaceURI 255 { 256 get 257 { 258 return this.navigator.NamespaceURI; 259 } 260 } 261 262 public override XmlNameTable NameTable 263 { 264 get 265 { 266 return this.navigator.NameTable; 267 } 268 } 269 270 public override XPathNodeType NodeType 271 { 272 get 273 { 274 return this.navigator.NodeType; 275 } 276 } 277 278 public override string Prefix 279 { 280 get 281 { 282 return this.navigator.Prefix; 283 } 284 } 285 286 public override string Value 287 { 288 get 289 { 290 return this.navigator.Value; 291 } 292 } 293 294 public override string XmlLang 295 { 296 get 297 { 298 return this.navigator.XmlLang; 299 } 300 } 301 Clone()302 public override XPathNavigator Clone() 303 { 304 return new SafeSeekableNavigator(this); 305 } 306 307 #if NO CreateSafeXPathNavigator()308 internal SafeNavigator CreateSafeXPathNavigator() 309 { 310 return new SafeNavigator(this, this.navigator); 311 } 312 #endif ComparePosition(XPathNavigator navigator)313 public override XmlNodeOrder ComparePosition(XPathNavigator navigator) 314 { 315 if (navigator == null) 316 { 317 return XmlNodeOrder.Unknown; 318 } 319 320 SafeSeekableNavigator nav = navigator as SafeSeekableNavigator; 321 if (nav != null) 322 { 323 return this.navigator.ComparePosition(nav.navigator); 324 } 325 return XmlNodeOrder.Unknown; 326 } 327 ComparePosition(long x, long y)328 public override XmlNodeOrder ComparePosition(long x, long y) 329 { 330 return this.navigator.ComparePosition(x, y); 331 } 332 ElapsedCount(int marker)333 public int ElapsedCount(int marker) 334 { 335 return marker - this.counter.nodeCount; 336 } 337 GetLocalName(long nodePosition)338 public override string GetLocalName(long nodePosition) 339 { 340 return this.navigator.GetLocalName(nodePosition); 341 } 342 GetName(long nodePosition)343 public override string GetName(long nodePosition) 344 { 345 return this.navigator.GetName(nodePosition); 346 } 347 GetNamespace(long nodePosition)348 public override string GetNamespace(long nodePosition) 349 { 350 return this.navigator.GetNamespace(nodePosition); 351 } 352 GetNodeType(long nodePosition)353 public override XPathNodeType GetNodeType(long nodePosition) 354 { 355 return this.navigator.GetNodeType(nodePosition); 356 } 357 GetValue(long nodePosition)358 public override string GetValue(long nodePosition) 359 { 360 return this.navigator.GetValue(nodePosition); 361 } 362 GetNamespace(string name)363 public override string GetNamespace(string name) 364 { 365 this.IncrementNodeCount(); 366 return this.navigator.GetNamespace(name); 367 } 368 GetAttribute(string localName, string namespaceURI)369 public override string GetAttribute(string localName, string namespaceURI) 370 { 371 this.IncrementNodeCount(); 372 return this.navigator.GetAttribute(localName, namespaceURI); 373 } 374 Increase()375 public void Increase() 376 { 377 this.IncrementNodeCount(); 378 } 379 IncreaseBy(int count)380 public void IncreaseBy(int count) 381 { 382 this.counter.nodeCount -= (count - 1); 383 Increase(); 384 } 385 IncrementNodeCount()386 internal void IncrementNodeCount() 387 { 388 if (this.counter.nodeCount > 0) 389 { 390 this.counter.nodeCount--; 391 } 392 else 393 { 394 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XPathNavigatorException(SR.GetString(SR.FilterNodeQuotaExceeded, this.counter.nodeCountMax))); 395 } 396 } 397 #if NO Init(SeekableXPathNavigator navigator, int nodeCountMax)398 internal virtual void Init(SeekableXPathNavigator navigator, int nodeCountMax) 399 { 400 this.navigator = navigator; 401 this.nodeCount = nodeCountMax; 402 this.counter = this; 403 } 404 #endif IsDescendant(XPathNavigator navigator)405 public override bool IsDescendant(XPathNavigator navigator) 406 { 407 if (navigator == null) 408 { 409 return false; 410 } 411 412 SafeSeekableNavigator nav = navigator as SafeSeekableNavigator; 413 if (nav != null) 414 { 415 return this.navigator.IsDescendant(nav.navigator); 416 } 417 return false; 418 } 419 IsSamePosition(XPathNavigator other)420 public override bool IsSamePosition(XPathNavigator other) 421 { 422 if (other == null) 423 { 424 return false; 425 } 426 427 SafeSeekableNavigator nav = other as SafeSeekableNavigator; 428 if (nav != null) 429 { 430 return this.navigator.IsSamePosition(nav.navigator); 431 } 432 return false; 433 } 434 MoveToRoot()435 public override void MoveToRoot() 436 { 437 this.IncrementNodeCount(); 438 this.navigator.MoveToRoot(); 439 } 440 MoveToNextNamespace(XPathNamespaceScope namespaceScope)441 public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope) 442 { 443 this.IncrementNodeCount(); 444 return this.navigator.MoveToNextNamespace(namespaceScope); 445 } 446 MoveToNextAttribute()447 public override bool MoveToNextAttribute() 448 { 449 this.IncrementNodeCount(); 450 return this.navigator.MoveToNextAttribute(); 451 } 452 MoveToPrevious()453 public override bool MoveToPrevious() 454 { 455 this.IncrementNodeCount(); 456 return this.navigator.MoveToPrevious(); 457 } 458 MoveToFirstAttribute()459 public override bool MoveToFirstAttribute() 460 { 461 this.IncrementNodeCount(); 462 return this.navigator.MoveToFirstAttribute(); 463 } 464 MoveToNamespace(string name)465 public override bool MoveToNamespace(string name) 466 { 467 this.IncrementNodeCount(); 468 return this.navigator.MoveToNamespace(name); 469 } 470 MoveToParent()471 public override bool MoveToParent() 472 { 473 this.IncrementNodeCount(); 474 return this.navigator.MoveToParent(); 475 } 476 MoveTo(XPathNavigator other)477 public override bool MoveTo(XPathNavigator other) 478 { 479 if (other == null) 480 { 481 return false; 482 } 483 484 this.IncrementNodeCount(); 485 SafeSeekableNavigator nav = other as SafeSeekableNavigator; 486 if (nav != null) 487 { 488 return this.navigator.MoveTo(nav.navigator); 489 } 490 return false; 491 } 492 MoveToId(string id)493 public override bool MoveToId(string id) 494 { 495 this.IncrementNodeCount(); 496 return this.navigator.MoveToId(id); 497 } 498 MoveToFirstChild()499 public override bool MoveToFirstChild() 500 { 501 this.IncrementNodeCount(); 502 return this.navigator.MoveToFirstChild(); 503 } 504 MoveToFirstNamespace(XPathNamespaceScope namespaceScope)505 public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) 506 { 507 this.IncrementNodeCount(); 508 return this.navigator.MoveToFirstNamespace(namespaceScope); 509 } 510 MoveToAttribute(string localName, string namespaceURI)511 public override bool MoveToAttribute(string localName, string namespaceURI) 512 { 513 this.IncrementNodeCount(); 514 return this.navigator.MoveToAttribute(localName, namespaceURI); 515 } 516 MoveToNext()517 public override bool MoveToNext() 518 { 519 this.IncrementNodeCount(); 520 return this.navigator.MoveToNext(); 521 } 522 MoveToFirst()523 public override bool MoveToFirst() 524 { 525 this.IncrementNodeCount(); 526 return this.navigator.MoveToFirst(); 527 } 528 } 529 530 /// <summary> 531 /// The filter engine works with seekable navigators. This class takes a generic XPathNavigator implementation 532 /// and transforms it into a seekable navigator. Seekable navigators associate a 'position' to every node in a DOM. 533 /// 534 /// This class maintains a (position, navigator) map. Cloning navigators is unavoidable - XPathNavigator offers 535 /// no other way to snapshot its current position. However, caching allows memory allocations to be avoided - but 536 /// only once the navigator is warmed up. 537 /// </summary> 538 internal class GenericSeekableNavigator : SeekableXPathNavigator 539 { 540 QueryBuffer<XPathNavigator> nodes; 541 long currentPosition; 542 XPathNavigator navigator; 543 544 GenericSeekableNavigator dom; 545 #if NO GenericSeekableNavigator()546 internal GenericSeekableNavigator() 547 { 548 this.nodes = new QueryBuffer<XPathNavigator>(4); 549 this.currentPosition = -1; 550 } 551 #endif GenericSeekableNavigator(XPathNavigator navigator)552 internal GenericSeekableNavigator(XPathNavigator navigator) 553 { 554 this.navigator = navigator; 555 this.nodes = new QueryBuffer<XPathNavigator>(4); 556 this.currentPosition = -1; 557 this.dom = this; 558 } 559 GenericSeekableNavigator(GenericSeekableNavigator navigator)560 internal GenericSeekableNavigator(GenericSeekableNavigator navigator) 561 { 562 this.navigator = navigator.navigator.Clone(); 563 this.nodes = default(QueryBuffer<XPathNavigator>); 564 this.currentPosition = navigator.currentPosition; 565 this.dom = navigator.dom; 566 } 567 568 public override string BaseURI 569 { 570 get 571 { 572 return this.navigator.BaseURI; 573 } 574 } 575 576 public override bool HasAttributes 577 { 578 get 579 { 580 return this.navigator.HasAttributes; 581 } 582 } 583 584 public override bool HasChildren 585 { 586 get 587 { 588 return this.navigator.HasChildren; 589 } 590 } 591 592 #if NO 593 internal XPathNavigator InternalNavigator 594 { 595 get 596 { 597 return this.navigator; 598 } 599 } 600 #endif 601 public override bool IsEmptyElement 602 { 603 get 604 { 605 return this.navigator.IsEmptyElement; 606 } 607 } 608 609 public override string LocalName 610 { 611 get 612 { 613 return this.navigator.LocalName; 614 } 615 } 616 617 public override string Name 618 { 619 get 620 { 621 return this.navigator.Name; 622 } 623 } 624 625 public override string NamespaceURI 626 { 627 get 628 { 629 return this.navigator.NamespaceURI; 630 } 631 } 632 633 public override XmlNameTable NameTable 634 { 635 get 636 { 637 return this.navigator.NameTable; 638 } 639 } 640 641 public override XPathNodeType NodeType 642 { 643 get 644 { 645 return this.navigator.NodeType; 646 } 647 } 648 649 public override string Prefix 650 { 651 get 652 { 653 return this.navigator.Prefix; 654 } 655 } 656 657 public override string Value 658 { 659 get 660 { 661 return this.navigator.Value; 662 } 663 } 664 665 public override string XmlLang 666 { 667 get 668 { 669 return this.navigator.XmlLang; 670 } 671 } 672 673 /// <summary> 674 /// Setting the current position moves this navigator to the location specified by the given position 675 /// </summary> 676 public override long CurrentPosition 677 { 678 get 679 { 680 if (-1 == this.currentPosition) 681 { 682 this.SnapshotNavigator(); 683 } 684 return this.currentPosition; 685 } 686 set 687 { 688 this.navigator.MoveTo(this[value]); 689 this.currentPosition = value; 690 } 691 } 692 693 /// <summary> 694 /// Return the XPathNavigator that has the given position 695 /// </summary> 696 internal XPathNavigator this[long nodePosition] 697 { 698 get 699 { 700 int pos = (int)nodePosition; 701 Fx.Assert(this.dom.nodes.IsValidIndex(pos) && null != this.dom.nodes[pos], ""); 702 return this.dom.nodes[pos]; 703 } 704 } 705 706 #if NO Clear()707 internal virtual void Clear() 708 { 709 this.navigator = null; 710 this.currentPosition = -1; 711 } 712 #endif Clone()713 public override XPathNavigator Clone() 714 { 715 return new GenericSeekableNavigator(this); 716 } 717 ComparePosition(XPathNavigator navigator)718 public override XmlNodeOrder ComparePosition(XPathNavigator navigator) 719 { 720 if (navigator == null) 721 { 722 return XmlNodeOrder.Unknown; 723 } 724 725 GenericSeekableNavigator nav = navigator as GenericSeekableNavigator; 726 if (nav != null) 727 { 728 return this.navigator.ComparePosition(nav.navigator); 729 } 730 return XmlNodeOrder.Unknown; 731 } 732 ComparePosition(long x, long y)733 public override XmlNodeOrder ComparePosition(long x, long y) 734 { 735 XPathNavigator nodeX = this[x]; 736 XPathNavigator nodeY = this[y]; 737 738 return nodeX.ComparePosition(nodeY); 739 } 740 GetLocalName(long nodePosition)741 public override string GetLocalName(long nodePosition) 742 { 743 return this[nodePosition].LocalName; 744 } 745 GetName(long nodePosition)746 public override string GetName(long nodePosition) 747 { 748 return this[nodePosition].Name; 749 } 750 GetNamespace(long nodePosition)751 public override string GetNamespace(long nodePosition) 752 { 753 return this[nodePosition].NamespaceURI; 754 } 755 GetNodeType(long nodePosition)756 public override XPathNodeType GetNodeType(long nodePosition) 757 { 758 return this[nodePosition].NodeType; 759 } 760 GetValue(long nodePosition)761 public override string GetValue(long nodePosition) 762 { 763 return this[nodePosition].Value; 764 } 765 GetNamespace(string name)766 public override string GetNamespace(string name) 767 { 768 return this.navigator.GetNamespace(name); 769 } 770 GetAttribute(string localName, string namespaceURI)771 public override string GetAttribute(string localName, string namespaceURI) 772 { 773 return this.navigator.GetAttribute(localName, namespaceURI); 774 } 775 776 #if NO Init(XPathNavigator navigator)777 internal void Init(XPathNavigator navigator) 778 { 779 Fx.Assert(null != navigator, ""); 780 this.navigator = navigator; 781 this.currentPosition = -1; 782 } 783 #endif IsDescendant(XPathNavigator navigator)784 public override bool IsDescendant(XPathNavigator navigator) 785 { 786 if (navigator == null) 787 { 788 return false; 789 } 790 791 GenericSeekableNavigator nav = navigator as GenericSeekableNavigator; 792 if (null != nav) 793 { 794 return this.navigator.IsDescendant(nav.navigator); 795 } 796 return false; 797 } 798 IsSamePosition(XPathNavigator other)799 public override bool IsSamePosition(XPathNavigator other) 800 { 801 GenericSeekableNavigator nav = other as GenericSeekableNavigator; 802 if (null != nav) 803 { 804 return this.navigator.IsSamePosition(nav.navigator); 805 } 806 return false; 807 } 808 MoveToRoot()809 public override void MoveToRoot() 810 { 811 this.currentPosition = -1; 812 this.navigator.MoveToRoot(); 813 } 814 MoveToNextNamespace(XPathNamespaceScope namespaceScope)815 public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope) 816 { 817 this.currentPosition = -1; 818 return this.navigator.MoveToNextNamespace(namespaceScope); 819 } 820 MoveToNextAttribute()821 public override bool MoveToNextAttribute() 822 { 823 this.currentPosition = -1; 824 return this.navigator.MoveToNextAttribute(); 825 } 826 MoveToPrevious()827 public override bool MoveToPrevious() 828 { 829 this.currentPosition = -1; 830 return this.navigator.MoveToPrevious(); 831 } 832 MoveToFirstAttribute()833 public override bool MoveToFirstAttribute() 834 { 835 this.currentPosition = -1; 836 return this.navigator.MoveToFirstAttribute(); 837 } 838 MoveToNamespace(string name)839 public override bool MoveToNamespace(string name) 840 { 841 this.currentPosition = -1; 842 return this.navigator.MoveToNamespace(name); 843 } 844 MoveToParent()845 public override bool MoveToParent() 846 { 847 this.currentPosition = -1; 848 return this.navigator.MoveToParent(); 849 } 850 MoveTo(XPathNavigator other)851 public override bool MoveTo(XPathNavigator other) 852 { 853 GenericSeekableNavigator nav = other as GenericSeekableNavigator; 854 if (null != nav) 855 { 856 if (this.navigator.MoveTo(nav.navigator)) 857 { 858 this.currentPosition = nav.currentPosition; 859 return true; 860 } 861 } 862 863 return false; 864 } 865 MoveToId(string id)866 public override bool MoveToId(string id) 867 { 868 this.currentPosition = -1; 869 return this.navigator.MoveToId(id); 870 } 871 MoveToFirstChild()872 public override bool MoveToFirstChild() 873 { 874 this.currentPosition = -1; 875 return this.navigator.MoveToFirstChild(); 876 } 877 MoveToFirstNamespace(XPathNamespaceScope namespaceScope)878 public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) 879 { 880 this.currentPosition = -1; 881 return this.navigator.MoveToFirstNamespace(namespaceScope); 882 } 883 MoveToAttribute(string localName, string namespaceURI)884 public override bool MoveToAttribute(string localName, string namespaceURI) 885 { 886 this.currentPosition = -1; 887 return this.navigator.MoveToAttribute(localName, namespaceURI); 888 } 889 MoveToNext()890 public override bool MoveToNext() 891 { 892 this.currentPosition = -1; 893 return this.navigator.MoveToNext(); 894 } 895 MoveToFirst()896 public override bool MoveToFirst() 897 { 898 this.currentPosition = -1; 899 return this.navigator.MoveToFirst(); 900 } 901 SnapshotNavigator()902 internal void SnapshotNavigator() 903 { 904 this.currentPosition = this.dom.nodes.Count; 905 this.dom.nodes.Add(this.navigator.Clone()); 906 /* 907 if (this.currentPosition < this.nodes.Count) 908 { 909 // Use a cached navigator 910 XPathNavigator clonedNavigator = this.nodes[(int)this.currentPosition]; 911 Fx.Assert(null != clonedNavigator, ""); 912 clonedNavigator.MoveTo(this); 913 } 914 else 915 { 916 this.nodes.Add(this.navigator.Clone()); 917 } 918 */ 919 } 920 921 #region IQueryBufferPool Members 922 #if NO 923 /// <summary> 924 /// Reset the pool by deleting it entirely and starting it over 925 /// </summary> Reset()926 public void Reset() 927 { 928 this.nodes.count = 0; 929 this.nodes.TrimToCount(); 930 } 931 Trim()932 public void Trim() 933 { 934 this.nodes.TrimToCount(); 935 } 936 #endif 937 #endregion 938 } 939 } 940