/* Copyright (C) 1998, 1999 Cygnus Solutions This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ package java.util; import java.io.Serializable; /** * @author Warren Levy * @date August 17, 1998. */ /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 * "The Java Language Specification", ISBN 0-201-63451-1 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com. * Status: Believed complete and correct */ class VectorEnumeration implements Enumeration { private int enumIndex; private Vector enumVec; public VectorEnumeration(Vector vec) { enumVec = vec; enumIndex = 0; } public boolean hasMoreElements() { return enumIndex < enumVec.size(); } public Object nextElement() { if (!hasMoreElements()) throw new NoSuchElementException(); return enumVec.elementData[enumIndex++]; } } // TODO12: // public class Vector extends AbstractList // implements List, Cloneable, Serializable public class Vector implements Cloneable, Serializable { /* The size of the increment to use when growing this vector. The default of 0 means to double the capacity when growing. */ protected int capacityIncrement; /* The number of elements currently in elementData */ protected int elementCount; /* The buffer in which elements of this vector are stored */ protected Object[] elementData; public Vector() { this(10, 0); } public Vector(int initCap) { this(initCap, 0); } public Vector(int initCap, int capIncrement) { if (initCap < 0) throw new IllegalArgumentException (); elementData = new Object[initCap]; capacityIncrement = capIncrement; elementCount = 0; } public final synchronized void addElement(Object obj) { // Make sure there's room for a new element if (elementCount == elementData.length) ensureCapacity(elementCount+1); elementData[elementCount++] = obj; } public final int capacity() { return elementData.length; } public synchronized Object clone() { // New vector needs to have same size, capacity and capacityIncrement Vector newVec = new Vector(elementData.length, capacityIncrement); System.arraycopy(elementData, 0, newVec.elementData, 0, elementCount); newVec.elementCount = elementCount; return newVec; } public final boolean contains(Object obj) { for (int i = 0; i < elementCount; i++) { if (obj == null ? elementData[i] == null : obj.equals(elementData[i])) return true; } return false; } public final synchronized void copyInto(Object[] objArray) { System.arraycopy(elementData, 0, objArray, 0, elementCount); } public final synchronized Object elementAt(int idx) { if (idx < 0 || idx >= size()) throw new ArrayIndexOutOfBoundsException(); return elementData[idx]; } public final synchronized Enumeration elements() { return new VectorEnumeration(this); } public final synchronized void ensureCapacity(int minCap) { // Increasing the vector could make it much larger than minCap; // e.g. if minCap is just larger than the vector, size may double. // If someone cares about this possibility they should set capacityIncrement if (minCap > elementData.length) { // Increase the vector; double it if capacityIncrement is zero int newSize = elementData.length; newSize += (capacityIncrement > 0) ? capacityIncrement : elementData.length; // Make sure newSize is at least minCap if (newSize < minCap) newSize = minCap; Object[] newArray = new Object[newSize]; System.arraycopy(elementData, 0, newArray, 0, elementCount); elementData = newArray; } } public final synchronized Object firstElement() { if (elementCount == 0) throw new NoSuchElementException(); return elementData[0]; } public final int indexOf(Object obj) { return indexOf(obj, 0); } public final synchronized int indexOf(Object obj, int idx) { if (idx < 0) throw new IllegalArgumentException (); for (int i = idx; i < elementCount; i++) { if (obj == null ? elementData[i] == null : obj.equals(elementData[i])) return i; } return -1; } public final synchronized void insertElementAt(Object obj, int idx) { if (idx < 0 || idx > size()) throw new ArrayIndexOutOfBoundsException(); else if (idx == size()) // Spec says just use addElement() addElement(obj); else { // Make sure there's room for a new element if (elementCount == elementData.length) ensureCapacity(elementCount+1); // Shift the existing elements up and increment elementCount for (int i = elementCount++; i > idx; --i) elementData[i] = elementData[i-1]; elementData[idx] = obj; } } public final boolean isEmpty() { return elementCount == 0; } public final synchronized Object lastElement() { if (elementCount == 0) throw new NoSuchElementException(); return elementData[elementCount - 1]; } public final int lastIndexOf(Object obj) { return lastIndexOf(obj, size()-1); } public final synchronized int lastIndexOf(Object obj, int idx) { if (idx < 0) throw new IllegalArgumentException (); for (int i = idx; i >= 0; --i) { if (obj == null ? elementData[i] == null : obj.equals(elementData[i])) return i; } return -1; } public final synchronized void removeAllElements() { // Remove elements now to assist the gc in early cleanup for (int i = elementCount-1; i >= 0; --i) elementData[i] = null; elementCount = 0; } public final synchronized boolean removeElement(Object obj) { for (int i = 0; i < elementCount; i++) { if (obj == null ? elementData[i] == null : obj.equals(elementData[i])) { int j; // Decrement count first to ensure we don't walk off end of array --elementCount; for (j = i; j < elementCount; j++) elementData[j] = elementData[j+1]; // At this point, j was incrememented and points to old last element // Remove element now to assist the gc in early cleanup elementData[j] = null; return true; } } return false; } public final synchronized void removeElementAt(int idx) { int i; if (idx < 0 || idx >= size()) throw new ArrayIndexOutOfBoundsException(); // Decrement count first to ensure we don't walk off the end of the array --elementCount; for (i = idx; i < elementCount; i++) elementData[i] = elementData[i+1]; // At this point, i was incrememented and now points to the old last element // Remove element now to assist the gc in early cleanup elementData[i] = null; } public final synchronized void setElementAt(Object obj, int idx) { if (idx < 0 || idx >= size()) throw new ArrayIndexOutOfBoundsException(); elementData[idx] = obj; } public final synchronized void setSize(int newSize) { if (newSize < 0) throw new ArrayIndexOutOfBoundsException(); // Java Lang Spec p. 658 says to remove the excess elements and discard // when new size is smaller than old size. // When truncating, we could alternatively just reset elementCount instead // of freeing up the memory if the spec hadn't specified. The spec makes // sense though; if someone cares enough to call a setSize() function // they probably are doing so to free memory. if (newSize < elementCount) { elementCount = newSize; trimToSize(); } else if (newSize > elementCount) // Skip == case { // TBD: ensureCapacity() may create a vector much larger than newSize; // do we want to make the vector exactly newSize? Spec is unclear. ensureCapacity(newSize); // Make sure to null out new elements of grown vector for (int i = elementCount; i < newSize; i++) elementData[i] = null; elementCount = newSize; } } public final int size() { return elementCount; } public final synchronized String toString() { // Following the Java Lang Spec p. 656 // Prepend first element with open bracket StringBuffer result = new StringBuffer("["); if (elementCount > 0) // add first element if one exists result.append(elementData[0].toString()); // Prepend subsequent elements with ", " for (int i = 1; i < elementCount; i++) result.append(", ").append(elementData[i].toString()); // Append last element with closing bracket result.append("]"); return result.toString(); } public final synchronized void trimToSize() { // Give up excess storage capacity to save memory // // Don't bother checking for the case where size() == the capacity of the // vector since that is a much less likely case; it's more efficient to // not do the check and lose a bit of performance in that infrequent case Object[] newArray = new Object[elementCount]; System.arraycopy(elementData, 0, newArray, 0, elementCount); elementData = newArray; } // TODO12: // public Vector(Collection c) // { // } // TODO12: // public public boolean add(Object o) // { // } // TODO12: // public void add(int index, Object element) // { // } // TODO12: // public boolean addAll(Collection c) // { // } // TODO12: // public boolean addAll(int index, Collection c) // { // } // TODO12: // public void clear() // { // } // TODO12: // public boolean containsAll(Collection c) // { // } // TODO12: // public boolean equals(Object o) // { // } // TODO12: // public int hashCode() // { // } // TODO12: // public Object get(int index) // { // } // TODO12: // public boolean remove(Object o) // { // } // TODO12: // public Object remove(int index) // { // } // TODO12: // public boolean removeAll(Collection c) // { // } // TODO12: // public boolean retainAll(Collection c) // { // } // TODO12: // public Object set(int index, Object element) // { // } // TODO12: // public Object[] toArray() // { // } // TODO12: // public Object[] toArray(Object[] a) // { // } }