001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: BoolStack.java 468655 2006-10-28 07:12:06Z minchau $
020     */
021    package org.apache.xml.utils;
022    
023    
024    /**
025     * Simple stack for boolean values.
026     * @xsl.usage internal
027     */
028    public final class BoolStack implements Cloneable
029    {
030    
031      /** Array of boolean values          */
032      private boolean m_values[];
033    
034      /** Array size allocated           */
035      private int m_allocatedSize;
036    
037      /** Index into the array of booleans          */
038      private int m_index;
039    
040      /**
041       * Default constructor.  Note that the default
042       * block size is very small, for small lists.
043       */
044      public BoolStack()
045      {
046        this(32);
047      }
048    
049      /**
050       * Construct a IntVector, using the given block size.
051       *
052       * @param size array size to allocate
053       */
054      public BoolStack(int size)
055      {
056    
057        m_allocatedSize = size;
058        m_values = new boolean[size];
059        m_index = -1;
060      }
061    
062      /**
063       * Get the length of the list.
064       *
065       * @return Current length of the list
066       */
067      public final int size()
068      {
069        return m_index + 1;
070      }
071    
072      /**
073       * Clears the stack.
074       *
075       */
076      public final void clear()
077      {
078            m_index = -1;
079      }
080    
081      /**
082       * Pushes an item onto the top of this stack.
083       *
084       *
085       * @param val the boolean to be pushed onto this stack.
086       * @return  the <code>item</code> argument.
087       */
088      public final boolean push(boolean val)
089      {
090    
091        if (m_index == m_allocatedSize - 1)
092          grow();
093    
094        return (m_values[++m_index] = val);
095      }
096    
097      /**
098       * Removes the object at the top of this stack and returns that
099       * object as the value of this function.
100       *
101       * @return     The object at the top of this stack.
102       * @throws  EmptyStackException  if this stack is empty.
103       */
104      public final boolean pop()
105      {
106        return m_values[m_index--];
107      }
108    
109      /**
110       * Removes the object at the top of this stack and returns the
111       * next object at the top as the value of this function.
112       *
113       *
114       * @return Next object to the top or false if none there
115       */
116      public final boolean popAndTop()
117      {
118    
119        m_index--;
120    
121        return (m_index >= 0) ? m_values[m_index] : false;
122      }
123    
124      /**
125       * Set the item at the top of this stack  
126       *
127       *
128       * @param b Object to set at the top of this stack
129       */
130      public final void setTop(boolean b)
131      {
132        m_values[m_index] = b;
133      }
134    
135      /**
136       * Looks at the object at the top of this stack without removing it
137       * from the stack.
138       *
139       * @return     the object at the top of this stack.
140       * @throws  EmptyStackException  if this stack is empty.
141       */
142      public final boolean peek()
143      {
144        return m_values[m_index];
145      }
146    
147      /**
148       * Looks at the object at the top of this stack without removing it
149       * from the stack.  If the stack is empty, it returns false.
150       *
151       * @return     the object at the top of this stack.
152       */
153      public final boolean peekOrFalse()
154      {
155        return (m_index > -1) ? m_values[m_index] : false;
156      }
157    
158      /**
159       * Looks at the object at the top of this stack without removing it
160       * from the stack.  If the stack is empty, it returns true.
161       *
162       * @return     the object at the top of this stack.
163       */
164      public final boolean peekOrTrue()
165      {
166        return (m_index > -1) ? m_values[m_index] : true;
167      }
168    
169      /**
170       * Tests if this stack is empty.
171       *
172       * @return  <code>true</code> if this stack is empty;
173       *          <code>false</code> otherwise.
174       */
175      public boolean isEmpty()
176      {
177        return (m_index == -1);
178      }
179    
180      /**
181       * Grows the size of the stack
182       *
183       */
184      private void grow()
185      {
186    
187        m_allocatedSize *= 2;
188    
189        boolean newVector[] = new boolean[m_allocatedSize];
190    
191        System.arraycopy(m_values, 0, newVector, 0, m_index + 1);
192    
193        m_values = newVector;
194      }
195      
196      public Object clone() 
197        throws CloneNotSupportedException
198      {
199        return super.clone();
200      }
201    
202    }