/* * Copyright (c) 2000, 2008, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.imageio.stream; import java.io.DataInputStream;import java.io.EOFException;import java.io.IOException;import java.nio.ByteOrder;import java.util.Stack;import javax.imageio.IIOException; /** * An abstract class implementing the <code>ImageInputStream</code> interface. * This class is designed to reduce the number of methods that must * be implemented by subclasses. * * <p> In particular, this class handles most or all of the details of * byte order interpretation, buffering, mark/reset, discarding, * closing, and disposing. */public abstract class ImageInputStreamImpl implements ImageInputStream { private Stack markByteStack = new Stack(); private Stack markBitStack = new Stack(); private boolean isClosed = false; // Length of the buffer used for readFully(type[], int, int) private static final int BYTE_BUF_LENGTH = 8192; /** * Byte buffer used for readFully(type[], int, int). Note that this * array is also used for bulk reads in readShort(), readInt(), etc, so * it should be large enough to hold a primitive value (i.e. >= 8 bytes). * Also note that this array is package protected, so that it can be * used by ImageOutputStreamImpl in a similar manner. */ byte[] byteBuf = new byte[BYTE_BUF_LENGTH]; /** * The byte order of the stream as an instance of the enumeration * class <code>java.nio.ByteOrder</code>, where * <code>ByteOrder.BIG_ENDIAN</code> indicates network byte order * and <code>ByteOrder.LITTLE_ENDIAN</code> indicates the reverse * order. By default, the value is * <code>ByteOrder.BIG_ENDIAN</code>. */ protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN; /** * The current read position within the stream. Subclasses are * responsible for keeping this value current from any method they * override that alters the read position. */ protected long streamPos; /** * The current bit offset within the stream. Subclasses are * responsible for keeping this value current from any method they * override that alters the bit offset. */ protected int bitOffset; /** * The position prior to which data may be discarded. Seeking * to a smaller position is not allowed. <code>flushedPos</code> * will always be >= 0. */ protected long flushedPos = 0; /** * Constructs an <code>ImageInputStreamImpl</code>. */ public ImageInputStreamImpl() { } /** * Throws an <code>IOException</code> if the stream has been closed. * Subclasses may call this method from any of their methods that * require the stream not to be closed. * * @exception IOException if the stream is closed. */ protected final void checkClosed() throws IOException { if (isClosed) { throw new IOException("closed"); } } public void setByteOrder(ByteOrder byteOrder) { this.byteOrder = byteOrder; } public ByteOrder getByteOrder() { return byteOrder; } /** * Reads a single byte from the stream and returns it as an * <code>int</code> between 0 and 255. If EOF is reached, * <code>-1</code> is returned. * * <p> Subclasses must provide an implementation for this method. * The subclass implementation should update the stream position * before exiting. * * <p> The bit offset within the stream must be reset to zero before * the read occurs. * * @return the value of the next byte in the stream, or <code>-1</code> * if EOF is reached. * * @exception IOException if the stream has been closed. */ public abstract int read() throws IOException; /** * A convenience method that calls <code>read(b, 0, b.length)</code>. * * <p> The bit offset within the stream is reset to zero before * the read occurs. * * @return the number of bytes actually read, or <code>-1</code> * to indicate EOF. * * @exception NullPointerException if <code>b</code> is * <code>null</code>. * @exception IOException if an I/O error occurs. */ public int read(byte[] b) throws IOException { return read(b, 0, b.length); } /** * Reads up to <code>len</code> bytes from the stream, and stores * them into <code>b</code> starting at index <code>off</code>. * If no bytes can be read because the end of the stream has been * reached, <code>-1</code> is returned. * * <p> The bit offset within the stream must be reset to zero before * the read occurs. * * <p> Subclasses must provide an implementation for this method. * The subclass implementation should update the stream position * before exiting. * * @param b an array of bytes to be written to. * @param off the starting position within <code>b</code> to write to. * @param len the maximum number of bytes to read. * * @return the number of bytes actually read, or <code>-1</code> * to indicate EOF. * * @exception IndexOutOfBoundsException if <code>off</code> is * negative, <code>len</code> is negative, or <code>off + * len</code> is greater than <code>b.length</code>. * @exception NullPointerException if <code>b</code> is * <code>null</code>. * @exception IOException if an I/O error occurs. */ public abstract int read(byte[] b, int off, int len) throws IOException; public void readBytes(IIOByteBuffer buf, int len) throws IOException { if (len < 0) { throw new IndexOutOfBoundsException("len < 0!"); } if (buf == null) { throw new NullPointerException("buf == null!"); } byte[] data = new byte[len]; len = read(data, 0, len); buf.setData(data); buf.setOffset(0); buf.setLength(len); } public boolean readBoolean() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return (ch != 0); } public byte readByte() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return (byte)ch; } public int readUnsignedByte() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return ch; } public short readShort() throws IOException { if (read(byteBuf, 0, 2) < 0) { throw new EOFException(); } if (byteOrder == ByteOrder.BIG_ENDIAN) { return (short) (((byteBuf[0] & 0xff) << 8) | ((byteBuf[1] & 0xff) << 0)); } else { return (short) (((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0)); } } public int readUnsignedShort() throws IOException { return ((int)readShort()) & 0xffff; } public char readChar() throws IOException { return (char)readShort(); } public int readInt() throws IOException { if (read(byteBuf, 0, 4) < 0) { throw new EOFException(); } if (byteOrder == ByteOrder.BIG_ENDIAN) { return (((byteBuf[0] & 0xff) << 24) | ((byteBuf[1] & 0xff) << 16) | ((byteBuf[2] & 0xff) << 8) | ((byteBuf[3] & 0xff) << 0)); } else { return (((byteBuf[3] & 0xff) << 24) | ((byteBuf[2] & 0xff) << 16) | ((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0)); } } public long readUnsignedInt() throws IOException { return ((long)readInt()) & 0xffffffffL; } public long readLong() throws IOException { // REMIND: Once 6277756 is fixed, we should do a bulk read of all 8 // bytes here as we do in readShort() and readInt() for even better // performance (see 6347575 for details). int i1 = readInt(); int i2 = readInt(); if (byteOrder == ByteOrder.BIG_ENDIAN) { return ((long)i1 << 32) + (i2 & 0xFFFFFFFFL); } else { return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL); } } public float readFloat() throws IOException { return Float.intBitsToFloat(readInt()); } public double readDouble() throws IOException { return Double.longBitsToDouble(readLong()); } public String readLine() throws IOException { StringBuffer input = new StringBuffer(); int c = -1; boolean eol = false; while (!eol) { switch (c = read()) { case -1: case '\n': eol = true; break; case '\r': eol = true; long cur = getStreamPosition(); if ((read()) != '\n') { seek(cur); } break; default: input.append((char)c); break; } } if ((c == -1) && (input.length() == 0)) { return null; } return input.toString(); } public String readUTF() throws IOException { this.bitOffset = 0; // Fix 4494369: method ImageInputStreamImpl.readUTF() // does not work as specified (it should always assume // network byte order). ByteOrder oldByteOrder = getByteOrder(); setByteOrder(ByteOrder.BIG_ENDIAN); String ret; try { ret = DataInputStream.readUTF(this); } catch (IOException e) { // Restore the old byte order even if an exception occurs setByteOrder(oldByteOrder); throw e; } setByteOrder(oldByteOrder); return ret; } public void readFully(byte[] b, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > b.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > b.length!"); } while (len > 0) { int nbytes = read(b, off, len); if (nbytes == -1) { throw new EOFException(); } off += nbytes; len -= nbytes; } } public void readFully(byte[] b) throws IOException { readFully(b, 0, b.length); } public void readFully(short[] s, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > s.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > s.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/2); readFully(byteBuf, 0, nelts*2); toShorts(byteBuf, s, off, nelts); off += nelts; len -= nelts; } } public void readFully(char[] c, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > c.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > c.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/2); readFully(byteBuf, 0, nelts*2); toChars(byteBuf, c, off, nelts); off += nelts; len -= nelts; } } public void readFully(int[] i, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > i.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > i.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/4); readFully(byteBuf, 0, nelts*4); toInts(byteBuf, i, off, nelts); off += nelts; len -= nelts; } } public void readFully(long[] l, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > l.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > l.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/8); readFully(byteBuf, 0, nelts*8); toLongs(byteBuf, l, off, nelts); off += nelts; len -= nelts; } } public void readFully(float[] f, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > f.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > f.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/4); readFully(byteBuf, 0, nelts*4); toFloats(byteBuf, f, off, nelts); off += nelts; len -= nelts; } } public void readFully(double[] d, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > d.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > d.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/8); readFully(byteBuf, 0, nelts*8); toDoubles(byteBuf, d, off, nelts); off += nelts; len -= nelts; } } private void toShorts(byte[] b, short[] s, int off, int len) { int boff = 0; if (byteOrder == ByteOrder.BIG_ENDIAN) { for (int j = 0; j < len; j++) { int b0 = b[boff]; int b1 = b[boff + 1] & 0xff; s[off + j] = (short)((b0 << 8) | b1); boff += 2; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 1]; int b1 = b[boff] & 0xff; s[off + j] = (short)((b0 << 8) | b1); boff += 2; } } } private void toChars(byte[] b, char[] c, int off, int len) { int boff = 0; if (byteOrder == ByteOrder.BIG_ENDIAN) { for (int j = 0; j < len; j++) { int b0 = b[boff]; int b1 = b[boff + 1] & 0xff; c[off + j] = (char)((b0 << 8) | b1); boff += 2; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 1]; int b1 = b[boff] & 0xff; c[off + j] = (char)((b0 << 8) | b1); boff += 2; } } } private void toInts(byte[] b, int[] i, int off, int len) { int boff = 0; if (byteOrder == ByteOrder.BIG_ENDIAN) {Lines 1–500 of 880. Load more
/* * Copyright (c) 2000, 2008, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.imageio.stream; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.nio.ByteOrder; import java.util.Stack; import javax.imageio.IIOException; /** * An abstract class implementing the <code>ImageInputStream</code> interface. * This class is designed to reduce the number of methods that must * be implemented by subclasses. * * <p> In particular, this class handles most or all of the details of * byte order interpretation, buffering, mark/reset, discarding, * closing, and disposing. */ public abstract class ImageInputStreamImpl implements ImageInputStream { private Stack markByteStack = new Stack(); private Stack markBitStack = new Stack(); private boolean isClosed = false; // Length of the buffer used for readFully(type[], int, int) private static final int BYTE_BUF_LENGTH = 8192; /** * Byte buffer used for readFully(type[], int, int). Note that this * array is also used for bulk reads in readShort(), readInt(), etc, so * it should be large enough to hold a primitive value (i.e. >= 8 bytes). * Also note that this array is package protected, so that it can be * used by ImageOutputStreamImpl in a similar manner. */ byte[] byteBuf = new byte[BYTE_BUF_LENGTH]; /** * The byte order of the stream as an instance of the enumeration * class <code>java.nio.ByteOrder</code>, where * <code>ByteOrder.BIG_ENDIAN</code> indicates network byte order * and <code>ByteOrder.LITTLE_ENDIAN</code> indicates the reverse * order. By default, the value is * <code>ByteOrder.BIG_ENDIAN</code>. */ protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN; /** * The current read position within the stream. Subclasses are * responsible for keeping this value current from any method they * override that alters the read position. */ protected long streamPos; /** * The current bit offset within the stream. Subclasses are * responsible for keeping this value current from any method they * override that alters the bit offset. */ protected int bitOffset; /** * The position prior to which data may be discarded. Seeking * to a smaller position is not allowed. <code>flushedPos</code> * will always be >= 0. */ protected long flushedPos = 0; /** * Constructs an <code>ImageInputStreamImpl</code>. */ public ImageInputStreamImpl() { } /** * Throws an <code>IOException</code> if the stream has been closed. * Subclasses may call this method from any of their methods that * require the stream not to be closed. * * @exception IOException if the stream is closed. */ protected final void checkClosed() throws IOException { if (isClosed) { throw new IOException("closed"); } } public void setByteOrder(ByteOrder byteOrder) { this.byteOrder = byteOrder; } public ByteOrder getByteOrder() { return byteOrder; } /** * Reads a single byte from the stream and returns it as an * <code>int</code> between 0 and 255. If EOF is reached, * <code>-1</code> is returned. * * <p> Subclasses must provide an implementation for this method. * The subclass implementation should update the stream position * before exiting. * * <p> The bit offset within the stream must be reset to zero before * the read occurs. * * @return the value of the next byte in the stream, or <code>-1</code> * if EOF is reached. * * @exception IOException if the stream has been closed. */ public abstract int read() throws IOException; /** * A convenience method that calls <code>read(b, 0, b.length)</code>. * * <p> The bit offset within the stream is reset to zero before * the read occurs. * * @return the number of bytes actually read, or <code>-1</code> * to indicate EOF. * * @exception NullPointerException if <code>b</code> is * <code>null</code>. * @exception IOException if an I/O error occurs. */ public int read(byte[] b) throws IOException { return read(b, 0, b.length); } /** * Reads up to <code>len</code> bytes from the stream, and stores * them into <code>b</code> starting at index <code>off</code>. * If no bytes can be read because the end of the stream has been * reached, <code>-1</code> is returned. * * <p> The bit offset within the stream must be reset to zero before * the read occurs. * * <p> Subclasses must provide an implementation for this method. * The subclass implementation should update the stream position * before exiting. * * @param b an array of bytes to be written to. * @param off the starting position within <code>b</code> to write to. * @param len the maximum number of bytes to read. * * @return the number of bytes actually read, or <code>-1</code> * to indicate EOF. * * @exception IndexOutOfBoundsException if <code>off</code> is * negative, <code>len</code> is negative, or <code>off + * len</code> is greater than <code>b.length</code>. * @exception NullPointerException if <code>b</code> is * <code>null</code>. * @exception IOException if an I/O error occurs. */ public abstract int read(byte[] b, int off, int len) throws IOException; public void readBytes(IIOByteBuffer buf, int len) throws IOException { if (len < 0) { throw new IndexOutOfBoundsException("len < 0!"); } if (buf == null) { throw new NullPointerException("buf == null!"); } byte[] data = new byte[len]; len = read(data, 0, len); buf.setData(data); buf.setOffset(0); buf.setLength(len); } public boolean readBoolean() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return (ch != 0); } public byte readByte() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return (byte)ch; } public int readUnsignedByte() throws IOException { int ch = this.read(); if (ch < 0) { throw new EOFException(); } return ch; } public short readShort() throws IOException { if (read(byteBuf, 0, 2) < 0) { throw new EOFException(); } if (byteOrder == ByteOrder.BIG_ENDIAN) { return (short) (((byteBuf[0] & 0xff) << 8) | ((byteBuf[1] & 0xff) << 0)); } else { return (short) (((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0)); } } public int readUnsignedShort() throws IOException { return ((int)readShort()) & 0xffff; } public char readChar() throws IOException { return (char)readShort(); } public int readInt() throws IOException { if (read(byteBuf, 0, 4) < 0) { throw new EOFException(); } if (byteOrder == ByteOrder.BIG_ENDIAN) { return (((byteBuf[0] & 0xff) << 24) | ((byteBuf[1] & 0xff) << 16) | ((byteBuf[2] & 0xff) << 8) | ((byteBuf[3] & 0xff) << 0)); } else { return (((byteBuf[3] & 0xff) << 24) | ((byteBuf[2] & 0xff) << 16) | ((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0)); } } public long readUnsignedInt() throws IOException { return ((long)readInt()) & 0xffffffffL; } public long readLong() throws IOException { // REMIND: Once 6277756 is fixed, we should do a bulk read of all 8 // bytes here as we do in readShort() and readInt() for even better // performance (see 6347575 for details). int i1 = readInt(); int i2 = readInt(); if (byteOrder == ByteOrder.BIG_ENDIAN) { return ((long)i1 << 32) + (i2 & 0xFFFFFFFFL); } else { return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL); } } public float readFloat() throws IOException { return Float.intBitsToFloat(readInt()); } public double readDouble() throws IOException { return Double.longBitsToDouble(readLong()); } public String readLine() throws IOException { StringBuffer input = new StringBuffer(); int c = -1; boolean eol = false; while (!eol) { switch (c = read()) { case -1: case '\n': eol = true; break; case '\r': eol = true; long cur = getStreamPosition(); if ((read()) != '\n') { seek(cur); } break; default: input.append((char)c); break; } } if ((c == -1) && (input.length() == 0)) { return null; } return input.toString(); } public String readUTF() throws IOException { this.bitOffset = 0; // Fix 4494369: method ImageInputStreamImpl.readUTF() // does not work as specified (it should always assume // network byte order). ByteOrder oldByteOrder = getByteOrder(); setByteOrder(ByteOrder.BIG_ENDIAN); String ret; try { ret = DataInputStream.readUTF(this); } catch (IOException e) { // Restore the old byte order even if an exception occurs setByteOrder(oldByteOrder); throw e; } setByteOrder(oldByteOrder); return ret; } public void readFully(byte[] b, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > b.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > b.length!"); } while (len > 0) { int nbytes = read(b, off, len); if (nbytes == -1) { throw new EOFException(); } off += nbytes; len -= nbytes; } } public void readFully(byte[] b) throws IOException { readFully(b, 0, b.length); } public void readFully(short[] s, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > s.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > s.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/2); readFully(byteBuf, 0, nelts*2); toShorts(byteBuf, s, off, nelts); off += nelts; len -= nelts; } } public void readFully(char[] c, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > c.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > c.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/2); readFully(byteBuf, 0, nelts*2); toChars(byteBuf, c, off, nelts); off += nelts; len -= nelts; } } public void readFully(int[] i, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > i.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > i.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/4); readFully(byteBuf, 0, nelts*4); toInts(byteBuf, i, off, nelts); off += nelts; len -= nelts; } } public void readFully(long[] l, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > l.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > l.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/8); readFully(byteBuf, 0, nelts*8); toLongs(byteBuf, l, off, nelts); off += nelts; len -= nelts; } } public void readFully(float[] f, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > f.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > f.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/4); readFully(byteBuf, 0, nelts*4); toFloats(byteBuf, f, off, nelts); off += nelts; len -= nelts; } } public void readFully(double[] d, int off, int len) throws IOException { // Fix 4430357 - if off + len < 0, overflow occurred if (off < 0 || len < 0 || off + len > d.length || off + len < 0) { throw new IndexOutOfBoundsException ("off < 0 || len < 0 || off + len > d.length!"); } while (len > 0) { int nelts = Math.min(len, byteBuf.length/8); readFully(byteBuf, 0, nelts*8); toDoubles(byteBuf, d, off, nelts); off += nelts; len -= nelts; } } private void toShorts(byte[] b, short[] s, int off, int len) { int boff = 0; if (byteOrder == ByteOrder.BIG_ENDIAN) { for (int j = 0; j < len; j++) { int b0 = b[boff]; int b1 = b[boff + 1] & 0xff; s[off + j] = (short)((b0 << 8) | b1); boff += 2; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 1]; int b1 = b[boff] & 0xff; s[off + j] = (short)((b0 << 8) | b1); boff += 2; } } } private void toChars(byte[] b, char[] c, int off, int len) { int boff = 0; if (byteOrder == ByteOrder.BIG_ENDIAN) { for (int j = 0; j < len; j++) { int b0 = b[boff]; int b1 = b[boff + 1] & 0xff; c[off + j] = (char)((b0 << 8) | b1); boff += 2; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 1]; int b1 = b[boff] & 0xff; c[off + j] = (char)((b0 << 8) | b1); boff += 2; } } } private void toInts(byte[] b, int[] i, int off, int len) { int boff = 0; if (byteOrder == ByteOrder.BIG_ENDIAN) {