/* * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package org.visage.runtime.sequence; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; import org.visage.runtime.TypeInfo; import org.visage.runtime.Util; /** * Relatively inefficient implementation of a mutable sequence with a slice-replace operation. This is used internally * in sequence binding implementations. * * @author Brian Goetz */ public class DumbMutableSequence<T> implements Iterable<T> { private T[] array; private int size; public DumbMutableSequence(T[] initialValues) { this(initialValues.length); System.arraycopy(initialValues, 0, array, 0, initialValues.length); size = initialValues.length; } public DumbMutableSequence(int initialSize) { this.array = Util.<T>newObjectArray(Util.powerOfTwo(1, initialSize)); size = 0; } public DumbMutableSequence() { this(8); } public T get(int i) { return (i < 0 || i >= size) ? null : array[i]; } public void set(int i, T value) { if (i < 0 && i > size) throw new IndexOutOfBoundsException(Integer.toString(i)); if (i == size && size + 1 < array.length) { T[] temp = Util.<T>newObjectArray(Util.powerOfTwo(size, size + 1)); System.arraycopy(array, 0, temp, 0, size); array[size++] = value; } else array[i] = value; } public void replaceSlice(int startPos, int endPos/*exclusive*/, T[] newElements) { int insertedCount = newElements.length; int deletedCount = endPos - startPos; int netAdded = insertedCount - deletedCount; if (netAdded == 0) System.arraycopy(newElements, 0, array, startPos, insertedCount); else if (size + netAdded < array.length) { System.arraycopy(array, endPos, array, endPos + netAdded, size - endPos); System.arraycopy(newElements, 0, array, startPos, insertedCount); if (netAdded < 0) Arrays.fill(array, size + netAdded, size, null); size += netAdded; } else { int newSize = size + netAdded; T[] temp = Util.<T>newObjectArray(Util.powerOfTwo(size, newSize)); System.arraycopy(array, 0, temp, 0, startPos); System.arraycopy(newElements, 0, temp, startPos, insertedCount); System.arraycopy(array, endPos, temp, startPos + insertedCount, size - endPos); array = temp; size = newSize; } } public Sequence<? extends T> replaceSlice(int startPos, int endPos/*exclusive*/, Sequence<? extends T> newElements) { final int length = Sequences.size(newElements); T[] temp = Util.<T>newObjectArray(length); newElements.toArray(0, length, temp, 0); replaceSlice(startPos, endPos, temp); return newElements; } public Sequence<T> get(Class<T> clazz) { return Sequences.make(TypeInfo.getTypeInfo(clazz), array, size); } public int size() { return size; } public Iterator<T> iterator() { return new Iterator<T>() { private int index = 0; public boolean hasNext() { return index < size; } public T next() { if (hasNext()) return array[index++]; else throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } }; } void testValid() { for (int i = 0; i < size; i++) if (array[i] == null) throw new AssertionError("Null element at " + i); for (int i = size; i < array.length; i++) if (array[i] != null) throw new AssertionError("Non-null element at " + i); } }