1 //------------------------------------------------------------------------------ 2 // <copyright file="HWStack.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // <owner current="true" primary="true">Microsoft</owner> 6 //------------------------------------------------------------------------------ 7 8 using System; 9 10 11 namespace System.Xml { 12 13 // This stack is designed to minimize object creation for the 14 // objects being stored in the stack by allowing them to be 15 // re-used over time. It basically pushes the objects creating 16 // a high water mark then as Pop() is called they are not removed 17 // so that next time Push() is called it simply returns the last 18 // object that was already on the stack. 19 20 internal class HWStack : ICloneable { HWStack(int GrowthRate)21 internal HWStack(int GrowthRate) : this (GrowthRate, int.MaxValue) {} 22 HWStack(int GrowthRate, int limit)23 internal HWStack(int GrowthRate, int limit) { 24 this.growthRate = GrowthRate; 25 this.used = 0; 26 this.stack = new Object[GrowthRate]; 27 this.size = GrowthRate; 28 this.limit = limit; 29 } 30 Push()31 internal Object Push() { 32 if (this.used == this.size) { 33 if (this.limit <= this.used) { 34 throw new XmlException(Res.Xml_StackOverflow, string.Empty); 35 } 36 Object[] newstack = new Object[this.size + this.growthRate]; 37 if (this.used > 0) { 38 System.Array.Copy(this.stack, 0, newstack, 0, this.used); 39 } 40 this.stack = newstack; 41 this.size += this.growthRate; 42 } 43 return this.stack[this.used++]; 44 } 45 Pop()46 internal Object Pop() { 47 if (0 < this.used) { 48 this.used--; 49 Object result = this.stack[this.used]; 50 return result; 51 } 52 return null; 53 } 54 Peek()55 internal object Peek() { 56 return this.used > 0 ? this.stack[this.used - 1] : null; 57 } 58 AddToTop(object o)59 internal void AddToTop(object o) { 60 if (this.used > 0) { 61 this.stack[this.used - 1] = o; 62 } 63 } 64 65 internal Object this[int index] { 66 get { 67 if (index >= 0 && index < this.used) { 68 Object result = this.stack[index]; 69 return result; 70 } 71 else { 72 throw new IndexOutOfRangeException(); 73 } 74 } 75 set { 76 if (index >= 0 && index < this.used) { 77 this.stack[index] = value; 78 } 79 else { 80 throw new IndexOutOfRangeException(); 81 } 82 } 83 } 84 85 internal int Length { 86 get { return this.used;} 87 } 88 89 // 90 // ICloneable 91 // 92 HWStack(object[] stack, int growthRate, int used, int size)93 private HWStack(object[] stack, int growthRate, int used, int size) { 94 this.stack = stack; 95 this.growthRate = growthRate; 96 this.used = used; 97 this.size = size; 98 } 99 Clone()100 public object Clone() { 101 return new HWStack((object[]) this.stack.Clone(), this.growthRate, this.used, this.size); 102 } 103 104 private Object[] stack; 105 private int growthRate; 106 private int used; 107 private int size; 108 private int limit; 109 }; 110 111 } 112