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