/* * Extended Static Checking Exercise * Fall 2013 CSCI181F - Verification-centric Software Engineering * Daniel M. Zimmerman */ /** * A class that implements a growable array of objects, based * on an old implementation of java.util.Vector - original source * by Lee Boynton and Jonathan Payne, Sun Microsystems. * * @author Daniel M. Zimmerman * @version 2013-10-24 (based on v1.38, 12/18/97) */ public class Vector { //@ public invariant my_element_data != null; //@ public invariant my_element_count >= 0; //@ public invariant my_element_count <= my_element_data.length; //@ public invariant my_capacity_increment > 0; /** * The array buffer into which the components of the vector are * stored. The capacity of the vector is the length of this array buffer. * * @since JDK1.0 */ //@ public invariant \elemtype(\typeof(my_element_data)) == \type(Object); private /*@ spec_public */ Object[] my_element_data; /** * The number of valid components in the vector. * * @since JDK1.0 */ private /*@ spec_public */ int my_element_count; /** * The amount by which the capacity of the vector is automatically * incremented when its size becomes greater than its capacity. If * the capacity increment is <code>0</code>, the capacity of the * vector is doubled each time it needs to grow. * * @since JDK1.0 */ private /*@ spec_public */ final int my_capacity_increment; /** * Constructs an empty vector with the specified initial capacity and * capacity increment. * * @param the_initial_capacity the initial capacity of the vector. * @param the_capacity_increment the amount by which the capacity is * increased when the vector overflows. * @since JDK1.0 */ //@ requires the_initial_capacity >= 0 && the_capacity_increment > 0; public Vector(final int the_initial_capacity, final int the_capacity_increment) { my_element_data = new Object[the_initial_capacity]; my_capacity_increment = the_capacity_increment; } /** * Adds an element to the vector. * * @param the_object The element to add. */ public final synchronized void add(final Object the_object) { if (my_element_count >= my_element_data.length) { // create a new array final Object[] new_data = new Object[my_element_count + my_capacity_increment]; // ERROR - could be negative //@ ghost Object[] nd = new_data; //@ loop_invariant 0 <= i && i <= my_element_count && new_data == nd; //@ decreases my_element_count - i; for (int i = 0; i < my_element_count; i++) { new_data[i] = my_element_data[i]; } my_element_data = new_data; } my_element_data[my_element_count++] = the_object; } /** * Copies the components of this vector into the specified array. * The array must be big enough to hold all the objects in this vector. * * @param the_array the array into which the components get copied. * @since JDK1.0 */ public final synchronized void copyInto(final Object[] the_array) { int i = my_element_count; //@ loop_invariant 0 <= i && i <= my_element_count; //@ decreases i; while (i-- > 0) { the_array[i] = my_element_data[i]; } } /** * Searches for the first occurrence of the given argument, beginning the * search at <code>index</code>, and testing for equality using the * <code>equals</code> method. * * @param the_elem an object. * @param the_index the index to start searching from. * @return the index of the first occurrence of the object argument in this * vector at position <code>index</code> or later in the vector; * returns <code>-1</code> if the object is not found. * @see java.lang.Object#equals(java.lang.Object) * @since JDK1.0 */ public final synchronized int indexOf(final Object the_elem, final int the_index) { //@ loop_invariant the_index == i || (the_index <= i && i <= my_element_count); //@ decreases my_element_count - i; for (int i = the_index; i < my_element_count; i++) { if (the_elem.equals(my_element_data[i])) { return i; } } return -1; } /** * Returns the component at the specified index. * * @param the_index an index into this vector. * @return the component at the specified index. * @exception ArrayIndexOutOfBoundsException if an invalid index was given. * @since JDK1.0 */ public final synchronized Object elementAt(final int the_index) throws ArrayIndexOutOfBoundsException { if (the_index >= my_element_count) { throw new ArrayIndexOutOfBoundsException(the_index + " >= " + my_element_count); } try { return my_element_data[the_index]; } catch (final ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException(the_index + " < 0"); } } }