/* * ome.util.mem.ByteArray * * Copyright 2006 University of Dundee. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.util.mem; import java.io.IOException; import java.io.InputStream; /** * A read-write slice of a given array. This class extends * {@link ReadOnlyByteArray} to allow for elements to be written to the array * slice. This class works just like its parent; so you get relative indexing * and any changes to the original array will be visible in the corresponding * <code>ByteArray</code> object, and vice-versa, any invocation of the * <code>set</code> methods will be reflected into the original array. * * @author Jean-Marie Burel      <a * href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author <br> * Andrea Falconi      <a * href="mailto:a.falconi@dundee.ac.uk"> a.falconi@dundee.ac.uk</a> * @version 2.2 <small> (<b>Internal version:</b> $Revision$ $Date: * 2005/06/09 15:01:57 $) </small> * @since OME2.2 */ public class ByteArray extends ReadOnlyByteArray { /** * Creates a read-write slice of <code>base</code>. The * <code>offset</code> argument marks the start of the slice, at * <code>base[offset]</code>. The <code>length</code> argument defines * the length of the slice, the last element being * <code>base[offset+length-1]</code>. Obviously enough, these two * arguments must define an interval <code>[offset, offset+length]</code> * in <code>[0, base.length]</code>. * * @param base * The original array. * @param offset * The start of the slice. * @param length * The length of the slice. */ public ByteArray(byte[] base, int offset, int length) { super(base, offset, length); } /** * Writes <code>value</code> into the element at the <code>index</code> * position within this slice. * * @param index * The index, within this slice, at which to write. Must be in * the <code>[0, {@link ReadOnlyByteArray#length})</code> * interval. * @param value * The value to write. */ public void set(int index, byte value) { checkIndex(index); base[offset + index] = value; } /** * Copies the values in <code>buf</code> into this slice, starting from * <code>index</code>. This method first checks to see whether * <code>buf.length</code> bytes can be written into this slice starting * from <code>index</code>. If the check fails an * {@link ArrayIndexOutOfBoundsException} is thrown and no data is copied at * all. * * @param index * The index, within this slice, from which to start writing. * Must be in the <code>[0, {@link ReadOnlyByteArray#length}) * </code> * interval. * @param buf * A buffer containing the values to write. Mustn't be * <code>null</code> and must fit into this slice. If the * length is <code>0</code>, then this method does nothing. * @throws NullPointerException * If a <code>null</code> buffer is specified. */ public void set(int index, byte[] buf) { if (buf == null) { throw new NullPointerException("No buffer."); } if (buf.length == 0) { return; } checkIndex(index); checkIndex(index + buf.length - 1); System.arraycopy(buf, 0, base, offset + index, buf.length); } /** * Writes up to <code>maxLength</code> bytes from the supplied stream into * this slice, starting from <code>index</code>. To be precise, this * method will attempt to write <code>m</code> bytes into this slice * (starting from the element at <code>index</code>), <code>m</code> * being the minimum of the following numbers: <code>maxLength</code>, * <code>this.{@link ReadOnlyByteArray#length length} - index</code> * (that is, bytes from <code>index</code> to the end of the slice), and * the number of bytes to the end of the supplied stream. * * @param index * The index, within this slice, from which to start writing. * Must be in the * <code>[0, {@link ReadOnlyByteArray#length})</code> * interval. * @param maxLength * The maximum amount of bytes to write. If not positive, this * method does nothing and returns <code>0</code>. * @param in * The stream from which to read data. Mustn't be * <code>null</code>. * @return The amount of bytes actually written or <code>-1</code> if the * end of the stream has been reached. * @throws IOException * If an I/O error occurred while reading data from the stream. * @throws NullPointerException * If the specified <code>input stream</code> is * <code>null</code>. */ public int set(int index, int maxLength, InputStream in) throws IOException { if (in == null) { throw new NullPointerException("No stream."); } if (maxLength <= 0) { return 0; } checkIndex(index); maxLength = index + maxLength <= length ? maxLength : length - index; return in.read(base, offset + index, maxLength); } }