/* * org.openmicroscopy.shoola.util.mem.ByteArray * *------------------------------------------------------------------------------ * Copyright (C) 2006 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program 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 for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.mem; //Java imports import java.io.IOException; import java.io.InputStream; //Third-party libraries //Application-internal dependencies /** * 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$) * </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. */ 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. */ 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); } }