HighWaterStack.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //
  2. // HighWaterStack.cs
  3. //
  4. // Authors:
  5. // Ben Maurer ([email protected])
  6. //
  7. // (C) 2003 Ben Maurer
  8. //
  9. namespace System.Xml {
  10. // This class represents a stack that minimizes object
  11. // allocation by using the "high water" method by allowing
  12. // objects to be reused over time. It would be much easier to do
  13. // with generics.
  14. //
  15. // To push an object one must use the following method:
  16. // Scope current = (Scope)scopes.Push ();
  17. // if (current == null) {
  18. // current = new Scope ();
  19. // scopes.AddToTop (current);
  20. // }
  21. // // set props of current
  22. internal class HighWaterStack : ICloneable {
  23. public HighWaterStack (int GrowthRate) : this (GrowthRate, int.MaxValue) {}
  24. public HighWaterStack (int GrowthRate, int limit)
  25. {
  26. growthrate = GrowthRate;
  27. used = 0;
  28. stack = new object [GrowthRate];
  29. size = GrowthRate;
  30. limit = limit;
  31. }
  32. public object Push ()
  33. {
  34. if (used == size) {
  35. if (limit <= used)
  36. throw new XmlException ("Xml Stack overflow!");
  37. size += growthrate;
  38. object [] newstack = new object [size];
  39. if (used > 0)
  40. Array.Copy (stack, 0, newstack, 0, used);
  41. stack = newstack;
  42. }
  43. return stack [used++];
  44. }
  45. public object Pop ()
  46. {
  47. if (used > 0)
  48. return stack [--used];
  49. return null;
  50. }
  51. public object Peek ()
  52. {
  53. return used > 0 ? stack[used - 1] : null;
  54. }
  55. public void AddToTop (object o)
  56. {
  57. if (used > 0)
  58. stack[used - 1] = o;
  59. }
  60. public object this [int index] {
  61. get {
  62. if (index >= 0 && index < used)
  63. return stack [index];
  64. throw new IndexOutOfRangeException ("index");
  65. }
  66. set {
  67. if (index >= 0 && index < used) stack [index] = value;
  68. throw new IndexOutOfRangeException ("index");
  69. }
  70. }
  71. public int Length {
  72. get { return used;}
  73. }
  74. public object Clone()
  75. {
  76. HighWaterStack ret = (HighWaterStack)this.MemberwiseClone ();
  77. ret.stack = (object [])this.stack.Clone ();
  78. return ret;
  79. }
  80. object [] stack;
  81. int growthrate;
  82. int used;
  83. int size;
  84. int limit;
  85. }
  86. }