//-< ArrayOfByte.java >----------------------------------------------*--------* // GOODS Version 2.02 (c) 1998 GARRET * ? * // (Generic Object Oriented Database System) * /\| * // GOODS Persistent Class Library * / \ * // Created: 1-Oct-98 K.A. Knizhnik * / [] \ * // Last update: 18-Oct-98 K.A. Knizhnik * GARRET * //-------------------------------------------------------------------*--------* // Dynamic array of bytes //-------------------------------------------------------------------*--------* package goodslib; import goodsjpi.*; /** * ArrayOfByte is just that, an array of bytes. It is fully * persistent, as it it's derived from Persistent. All reads cause a fetch of the * data, all writes mark it dirty and to be saved. * * @author K.A. Knizhnik * @version 1.0 */ public class ArrayOfByte extends AnyArray { protected byte[] array; public synchronized void putAt(int index, byte value) { if (index < 0 || index >= used) { throw new ArrayIndexOutOfBoundsException(index); } Metaobject.modify(); array[index] = value; } public synchronized byte getAt(int index) { if (index < 0 || index >= used) { throw new ArrayIndexOutOfBoundsException(index); } return array[index]; } public synchronized void changeSize(int newSize) { if (newSize < 0) { throw new ArrayIndexOutOfBoundsException(newSize); } int allocated = array.length; if (newSize > allocated) { allocated = (allocated*2 > newSize) ? allocated*2 : newSize; byte[] newArray = new byte[allocated]; System.arraycopy(array, 0, newArray, 0, used); array = newArray; } else if (newSize < used) { for (int i = used; --i >= newSize; array[i] = 0); } used = newSize; } public synchronized void insert(int index, int count, byte value) { if (count < 0) { throw new ArrayIndexOutOfBoundsException(count); } else if (index < 0 || index > used) { throw new ArrayIndexOutOfBoundsException(index); } changeSize(used+count); System.arraycopy(array, index, array, index+count, used-index-count); while (--count >= 0) { array[index++] = value; } } public synchronized void remove(int index, int count) { if (count < 0) { throw new ArrayIndexOutOfBoundsException(count); } else if (index < 0) { throw new ArrayIndexOutOfBoundsException(index); } else if (index+count > used) { throw new ArrayIndexOutOfBoundsException(index+count); } System.arraycopy(array, index+count, array, index, used-count-index); changeSize(used-count); } public synchronized void push(byte value) { changeSize(used+1); array[used-1] = value; } public synchronized byte pop() { if (used == 0) { throw new ArrayIndexOutOfBoundsException(0); } byte value = array[--used]; array[used] = 0; return value; } public synchronized byte top() { if (used == 0) { throw new ArrayIndexOutOfBoundsException(0); } return array[used-1]; } public synchronized void append(byte[] tail) { int size = used; changeSize(size + tail.length); System.arraycopy(tail, 0, array, size, tail.length); } public synchronized int compare(byte[] s) { int len = s.length; int n = len < used ? len : used; for (int i = 0; i < n; i++) { int diff = array[i] - s[i]; if (diff != 0) { return diff; } } return used - len; } public synchronized int compare(ArrayOfByte a) { int len = a.used; byte[] s = a.array; int n = len < used ? len : used; for (int i = 0; i < n; i++) { int diff = array[i] - s[i]; if (diff != 0) { return diff; } } return used - len; } public synchronized String toString() { return new String(array, 0, used); } public synchronized int hashCode() { char[] chars = new String(array, 0, used).toCharArray(); int h = 0; for (int i = 0, len = chars.length; i < len; i++) { h = 31*h + chars[i]; } return h; } public synchronized boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null) { return false; } if (obj instanceof String) { String s = (String)obj; int len = s.length(); if (len != used) { return false; } for (int i = 0; i < len; i++) { if (array[i] != s.charAt(i)) { return false; } } } else if (obj instanceof byte[]) { byte[] s = (byte[])obj; int len = s.length; if (len != used) { return false; } for (int i = 0; i < len; i++) { if (array[i] != s[i]) { return false; } } } else if (obj instanceof ArrayOfByte) { ArrayOfByte a = (ArrayOfByte)obj; int len = a.used; if (used != len) { return false; } for (int i = 0; i < len; i++) { if (array[i] != a.array[i]) { return false; } } } else { return false; } return true; } public synchronized byte[] toArray() { byte[] arr = new byte[used]; System.arraycopy(array, 0, arr, 0, used); return arr; } public synchronized void copy(int dstIndex, byte[] src, int srcIndex, int count) { if (dstIndex < 0) { throw new ArrayIndexOutOfBoundsException(dstIndex); } else if (dstIndex+count > used) { throw new ArrayIndexOutOfBoundsException(dstIndex+count); } Metaobject.modify(); System.arraycopy(src, srcIndex, array, dstIndex, count); } public synchronized int indexOf(byte val) { for (int i = 0; i < used; i++) { if (array[i] == val) { return i; } } return -1; } public synchronized int lastIndexOf(byte val) { for (int i = used; --i >= 0;) { if (array[i] == val) { return i; } } return -1; } public ArrayOfByte(int size) { this(size, size == 0 ? 16 : size); } public ArrayOfByte(int size, int allocatedSize) { Assert.that(size <= allocatedSize); array = new byte[allocatedSize]; used = size; } public ArrayOfByte(byte[] src) { int length = src.length; array = new byte[length]; used = length; System.arraycopy(src, 0, array, 0, length); } }