001    /*
002     * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003     *
004     * Redistribution and use in source and binary forms, with or without
005     * modification, are permitted provided that the following conditions are met:
006     *
007     *  o Redistributions of source code must retain the above copyright notice,
008     *    this list of conditions and the following disclaimer.
009     *
010     *  o Redistributions in binary form must reproduce the above copyright notice,
011     *    this list of conditions and the following disclaimer in the documentation
012     *    and/or other materials provided with the distribution.
013     *
014     *  o Neither the name of imagero Andrey Kuznetsov nor the names of
015     *    its contributors may be used to endorse or promote products derived
016     *    from this software without specific prior written permission.
017     *
018     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027     * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029     */
030    
031     package com.imagero.util;
032    
033    import java.util.EmptyStackException;
034    import java.util.Enumeration;
035    
036    /**
037     * Minimal Vector implementation without synchronization
038     */
039    public final class Vector {
040    
041        Object[] elements;
042    
043        int size;
044        int startSize;
045    
046    
047        public Vector() {
048            this(3);
049        }
050    
051        public Vector(int size) {
052            this.startSize = size;
053            this.elements = new Object[size];
054        }
055    
056        public void add(Object item) {
057            checkSize(size + 1);
058            elements[size++] = item;
059        }
060    
061        public void insert(Object item, int pos) {
062            checkSize(size + 1);
063            System.arraycopy(elements, pos, elements, pos + 1, size - pos);
064            elements[pos] = item;
065            size++;
066        }
067    
068        public Object pop() {
069            if (size > 0) {
070                size--;
071                Object obj = elements[size];
072                elements[size] = null;
073                return obj;
074            }
075            throw new EmptyStackException();
076        }
077    
078        public Object peek() {
079            if (size > 0) {
080                Object obj = elements[size - 1];
081                return obj;
082            }
083            throw new EmptyStackException();
084        }
085    
086        public int indexOf(Object o) {
087            if (o != null) {
088                for (int i = 0; i < size; i++) {
089                    if (elements[i] != null && elements[i].equals(o)) {
090                        return i;
091                    }
092                }
093            }
094            return -1;
095        }
096    
097        public boolean contains(Object o) {
098            return indexOf(o) >= 0;
099        }
100    
101        public boolean remove(Object o) {
102            int index = indexOf(o);
103            if (index >= 0) {
104                remove(index);
105            }
106            return index >= 0;
107        }
108    
109        public Object remove(int index) {
110            if (index >= 0 && index < size) {
111                Object obj = elements[index];
112                int length = size - index - 1;
113                if (length > 0) {
114                    System.arraycopy(elements, index + 1, elements, index, length);
115                    elements[size] = null;
116                }
117                size--;
118                return obj;
119            } else {
120                throw new IndexOutOfBoundsException("" + index);
121            }
122        }
123    
124        public void remove(int from, int count) {
125            if (from >= 0 && from + count <= size) {
126                int length = size - (from + count) - 1;
127                if (length > 0) {
128                    System.arraycopy(elements, from + count + 1, elements, from, length);
129                }
130                size -= count;
131                for (int i = 0; i < length; i++) {
132                    elements[size + i] = null;
133                }
134            } else {
135                throw new IndexOutOfBoundsException("" + from);
136            }
137        }
138    
139        public Object elementAt(int index) {
140            if (index >= 0 && index < size) {
141                Object obj = elements[index];
142                return obj;
143            } else {
144                throw new IndexOutOfBoundsException("" + index);
145            }
146        }
147    
148        /**
149         * replace element at given index.
150         * @param index element index
151         * @param o Object
152         * @return replaced Object
153         */
154        public Object setElementAt(int index, Object o) {
155            if (index >= 0 && index < size) {
156                Object tmp = elements[index];
157                elements[index] = o;
158                return tmp;
159            } else {
160                throw new IndexOutOfBoundsException("" + index);
161            }
162        }
163    
164        public int getCount() {
165            return size;
166        }
167    
168        public int size() {
169            return size;
170        }
171    
172        public boolean isEmpty() {
173            return size == 0;
174        }
175    
176        private void checkSize(int minSize) {
177            if (minSize > elements.length) {
178                Object oldData[] = elements;
179                elements = new Object[Math.max(minSize + 10, elements.length * 2)];
180                System.arraycopy(oldData, 0, elements, 0, size);
181            }
182        }
183    
184        public Enumeration elements() {
185            return new Enumeration() {
186                int pos;
187    
188                public boolean hasMoreElements() {
189                    return pos < getCount();
190                }
191    
192                public Object nextElement() {
193                    if (hasMoreElements()) {
194                        return elements[pos++];
195                    } else {
196                        throw new IndexOutOfBoundsException();
197                    }
198                }
199            };
200        }
201    
202        public int getCount(Class c) {
203            int count = 0;
204            for (int i = 0; i < elements.length; i++) {
205                if (c.isInstance(elements[i])) {
206                    count++;
207                }
208            }
209            return count;
210        }
211    
212        public void clear() {
213            elements = new Object[startSize];
214            size = 0;
215        }
216    
217        public void toArray(Object[] dest) {
218            System.arraycopy(elements, 0, dest, 0, Math.min(size, dest.length));
219        }
220    }