1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the  "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18/*
19 * $Id$
20 */
21package org.apache.xml.utils;
22
23import java.util.EmptyStackException;
24
25/**
26 * Implement a stack of simple integers.
27 *
28 * %OPT%
29 * This is currently based on ObjectVector, which permits fast acess but pays a
30 * heavy recopying penalty if/when its size is increased. If we expect deep
31 * stacks, we should consider a version based on ChunkedObjectVector.
32 * @xsl.usage internal
33 */
34public class ObjectStack extends ObjectVector
35{
36
37  /**
38   * Default constructor.  Note that the default
39   * block size is very small, for small lists.
40   */
41  public ObjectStack()
42  {
43    super();
44  }
45
46  /**
47   * Construct a ObjectVector, using the given block size.
48   *
49   * @param blocksize Size of block to allocate
50   */
51  public ObjectStack(int blocksize)
52  {
53    super(blocksize);
54  }
55
56  /**
57   * Copy constructor for ObjectStack
58   *
59   * @param v ObjectStack to copy
60   */
61  public ObjectStack (ObjectStack v)
62  {
63  	super(v);
64  }
65
66  /**
67   * Pushes an item onto the top of this stack.
68   *
69   * @param   i   the int to be pushed onto this stack.
70   * @return  the <code>item</code> argument.
71   */
72  public Object push(Object i)
73  {
74
75    if ((m_firstFree + 1) >= m_mapSize)
76    {
77      m_mapSize += m_blocksize;
78
79      Object newMap[] = new Object[m_mapSize];
80
81      System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
82
83      m_map = newMap;
84    }
85
86    m_map[m_firstFree] = i;
87
88    m_firstFree++;
89
90    return i;
91  }
92
93  /**
94   * Removes the object at the top of this stack and returns that
95   * object as the value of this function.
96   *
97   * @return     The object at the top of this stack.
98   */
99  public Object pop()
100  {
101    Object val = m_map[--m_firstFree];
102    m_map[m_firstFree] = null;
103
104    return val;
105  }
106
107  /**
108   * Quickly pops a number of items from the stack.
109   */
110
111  public void quickPop(int n)
112  {
113    m_firstFree -= n;
114  }
115
116  /**
117   * Looks at the object at the top of this stack without removing it
118   * from the stack.
119   *
120   * @return     the object at the top of this stack.
121   * @throws  EmptyStackException  if this stack is empty.
122   */
123  public Object peek()
124  {
125    try {
126      return m_map[m_firstFree - 1];
127    }
128    catch (ArrayIndexOutOfBoundsException e)
129    {
130      throw new EmptyStackException();
131    }
132  }
133
134  /**
135   * Looks at the object at the position the stack counting down n items.
136   *
137   * @param n The number of items down, indexed from zero.
138   * @return     the object at n items down.
139   * @throws  EmptyStackException  if this stack is empty.
140   */
141  public Object peek(int n)
142  {
143    try {
144      return m_map[m_firstFree-(1+n)];
145    }
146    catch (ArrayIndexOutOfBoundsException e)
147    {
148      throw new EmptyStackException();
149    }
150  }
151
152  /**
153   * Sets an object at a the top of the statck
154   *
155   *
156   * @param val object to set at the top
157   * @throws  EmptyStackException  if this stack is empty.
158   */
159  public void setTop(Object val)
160  {
161    try {
162      m_map[m_firstFree - 1] = val;
163    }
164    catch (ArrayIndexOutOfBoundsException e)
165    {
166      throw new EmptyStackException();
167    }
168  }
169
170  /**
171   * Tests if this stack is empty.
172   *
173   * @return  <code>true</code> if this stack is empty;
174   *          <code>false</code> otherwise.
175   * @since   JDK1.0
176   */
177  public boolean empty()
178  {
179    return m_firstFree == 0;
180  }
181
182  /**
183   * Returns where an object is on this stack.
184   *
185   * @param   o   the desired object.
186   * @return  the distance from the top of the stack where the object is]
187   *          located; the return value <code>-1</code> indicates that the
188   *          object is not on the stack.
189   * @since   JDK1.0
190   */
191  public int search(Object o)
192  {
193
194    int i = lastIndexOf(o);
195
196    if (i >= 0)
197    {
198      return size() - i;
199    }
200
201    return -1;
202  }
203
204  /**
205   * Returns clone of current ObjectStack
206   *
207   * @return clone of current ObjectStack
208   */
209  public Object clone()
210    throws CloneNotSupportedException
211  {
212  	return (ObjectStack) super.clone();
213  }
214
215}
216