for (int j = 0; j < len; j++) { int b0 = b[boff]; int b1 = b[boff + 1] & 0xff; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; boff += 4; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 3]; int b1 = b[boff + 2] & 0xff; int b2 = b[boff + 1] & 0xff; int b3 = b[boff] & 0xff; i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; boff += 4; } } } private void toLongs(byte[] b, long[] l, 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; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; int b4 = b[boff + 4]; int b5 = b[boff + 5] & 0xff; int b6 = b[boff + 6] & 0xff; int b7 = b[boff + 7] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL); boff += 8; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 7]; int b1 = b[boff + 6] & 0xff; int b2 = b[boff + 5] & 0xff; int b3 = b[boff + 4] & 0xff; int b4 = b[boff + 3]; int b5 = b[boff + 2] & 0xff; int b6 = b[boff + 1] & 0xff; int b7 = b[boff] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL); boff += 8; } } } private void toFloats(byte[] b, float[] f, 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; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; f[off + j] = Float.intBitsToFloat(i); boff += 4; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 3]; int b1 = b[boff + 2] & 0xff; int b2 = b[boff + 1] & 0xff; int b3 = b[boff + 0] & 0xff; int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; f[off + j] = Float.intBitsToFloat(i); boff += 4; } } } private void toDoubles(byte[] b, double[] d, 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; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; int b4 = b[boff + 4]; int b5 = b[boff + 5] & 0xff; int b6 = b[boff + 6] & 0xff; int b7 = b[boff + 7] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; long l = ((long)i0 << 32) | (i1 & 0xffffffffL); d[off + j] = Double.longBitsToDouble(l); boff += 8; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 7]; int b1 = b[boff + 6] & 0xff; int b2 = b[boff + 5] & 0xff; int b3 = b[boff + 4] & 0xff; int b4 = b[boff + 3]; int b5 = b[boff + 2] & 0xff; int b6 = b[boff + 1] & 0xff; int b7 = b[boff] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; long l = ((long)i0 << 32) | (i1 & 0xffffffffL); d[off + j] = Double.longBitsToDouble(l); boff += 8; } } } public long getStreamPosition() throws IOException { checkClosed(); return streamPos; } public int getBitOffset() throws IOException { checkClosed(); return bitOffset; } public void setBitOffset(int bitOffset) throws IOException { checkClosed(); if (bitOffset < 0 || bitOffset > 7) { throw new IllegalArgumentException("bitOffset must be betwwen 0 and 7!"); } this.bitOffset = bitOffset; } public int readBit() throws IOException { checkClosed(); // Compute final bit offset before we call read() and seek() int newBitOffset = (this.bitOffset + 1) & 0x7; int val = read(); if (val == -1) { throw new EOFException(); } if (newBitOffset != 0) { // Move byte position back if in the middle of a byte seek(getStreamPosition() - 1); // Shift the bit to be read to the rightmost position val >>= 8 - newBitOffset; } this.bitOffset = newBitOffset; return val & 0x1; } public long readBits(int numBits) throws IOException { checkClosed(); if (numBits < 0 || numBits > 64) { throw new IllegalArgumentException(); } if (numBits == 0) { return 0L; } // Have to read additional bits on the left equal to the bit offset int bitsToRead = numBits + bitOffset; // Compute final bit offset before we call read() and seek() int newBitOffset = (this.bitOffset + numBits) & 0x7; // Read a byte at a time, accumulate long accum = 0L; while (bitsToRead > 0) { int val = read(); if (val == -1) { throw new EOFException(); } accum <<= 8; accum |= val; bitsToRead -= 8; } // Move byte position back if in the middle of a byte if (newBitOffset != 0) { seek(getStreamPosition() - 1); } this.bitOffset = newBitOffset; // Shift away unwanted bits on the right. accum >>>= (-bitsToRead); // Negative of bitsToRead == extra bits read // Mask out unwanted bits on the left accum &= (-1L >>> (64 - numBits)); return accum; } /** * Returns <code>-1L</code> to indicate that the stream has unknown * length. Subclasses must override this method to provide actual * length information. * * @return -1L to indicate unknown length. */ public long length() { return -1L; } /** * Advances the current stream position by calling * <code>seek(getStreamPosition() + n)</code>. * * <p> The bit offset is reset to zero. * * @param n the number of bytes to seek forward. * * @return an <code>int</code> representing the number of bytes * skipped. * * @exception IOException if <code>getStreamPosition</code> * throws an <code>IOException</code> when computing either * the starting or ending position. */ public int skipBytes(int n) throws IOException { long pos = getStreamPosition(); seek(pos + n); return (int)(getStreamPosition() - pos); } /** * Advances the current stream position by calling * <code>seek(getStreamPosition() + n)</code>. * * <p> The bit offset is reset to zero. * * @param n the number of bytes to seek forward. * * @return a <code>long</code> representing the number of bytes * skipped. * * @exception IOException if <code>getStreamPosition</code> * throws an <code>IOException</code> when computing either * the starting or ending position. */ public long skipBytes(long n) throws IOException { long pos = getStreamPosition(); seek(pos + n); return getStreamPosition() - pos; } public void seek(long pos) throws IOException { checkClosed(); // This test also covers pos < 0 if (pos < flushedPos) { throw new IndexOutOfBoundsException("pos < flushedPos!"); } this.streamPos = pos; this.bitOffset = 0; } /** * Pushes the current stream position onto a stack of marked * positions. */ public void mark() { try { markByteStack.push(Long.valueOf(getStreamPosition())); markBitStack.push(Integer.valueOf(getBitOffset())); } catch (IOException e) { } } /** * Resets the current stream byte and bit positions from the stack * of marked positions. * * <p> An <code>IOException</code> will be thrown if the previous * marked position lies in the discarded portion of the stream. * * @exception IOException if an I/O error occurs. */ public void reset() throws IOException { if (markByteStack.empty()) { return; } long pos = ((Long)markByteStack.pop()).longValue(); if (pos < flushedPos) { throw new IIOException ("Previous marked position has been discarded!"); } seek(pos); int offset = ((Integer)markBitStack.pop()).intValue(); setBitOffset(offset); } public void flushBefore(long pos) throws IOException { checkClosed(); if (pos < flushedPos) { throw new IndexOutOfBoundsException("pos < flushedPos!"); } if (pos > getStreamPosition()) { throw new IndexOutOfBoundsException("pos > getStreamPosition()!"); } // Invariant: flushedPos >= 0 flushedPos = pos; } public void flush() throws IOException { flushBefore(getStreamPosition()); } public long getFlushedPosition() { return flushedPos; } /** * Default implementation returns false. Subclasses should * override this if they cache data. */ public boolean isCached() { return false; } /** * Default implementation returns false. Subclasses should * override this if they cache data in main memory. */ public boolean isCachedMemory() { return false; } /** * Default implementation returns false. Subclasses should * override this if they cache data in a temporary file. */ public boolean isCachedFile() { return false; } public void close() throws IOException { checkClosed(); isClosed = true; } /** * Finalizes this object prior to garbage collection. The * <code>close</code> method is called to close any open input * source. This method should not be called from application * code. * * @exception Throwable if an error occurs during superclass * finalization. */ protected void finalize() throws Throwable { if (!isClosed) { try { close(); } catch (IOException e) { } } super.finalize(); }}Lines 501–880 of 880. Previous lines
for (int j = 0; j < len; j++) { int b0 = b[boff]; int b1 = b[boff + 1] & 0xff; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; boff += 4; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 3]; int b1 = b[boff + 2] & 0xff; int b2 = b[boff + 1] & 0xff; int b3 = b[boff] & 0xff; i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; boff += 4; } } } private void toLongs(byte[] b, long[] l, 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; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; int b4 = b[boff + 4]; int b5 = b[boff + 5] & 0xff; int b6 = b[boff + 6] & 0xff; int b7 = b[boff + 7] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL); boff += 8; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 7]; int b1 = b[boff + 6] & 0xff; int b2 = b[boff + 5] & 0xff; int b3 = b[boff + 4] & 0xff; int b4 = b[boff + 3]; int b5 = b[boff + 2] & 0xff; int b6 = b[boff + 1] & 0xff; int b7 = b[boff] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL); boff += 8; } } } private void toFloats(byte[] b, float[] f, 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; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; f[off + j] = Float.intBitsToFloat(i); boff += 4; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 3]; int b1 = b[boff + 2] & 0xff; int b2 = b[boff + 1] & 0xff; int b3 = b[boff + 0] & 0xff; int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; f[off + j] = Float.intBitsToFloat(i); boff += 4; } } } private void toDoubles(byte[] b, double[] d, 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; int b2 = b[boff + 2] & 0xff; int b3 = b[boff + 3] & 0xff; int b4 = b[boff + 4]; int b5 = b[boff + 5] & 0xff; int b6 = b[boff + 6] & 0xff; int b7 = b[boff + 7] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; long l = ((long)i0 << 32) | (i1 & 0xffffffffL); d[off + j] = Double.longBitsToDouble(l); boff += 8; } } else { for (int j = 0; j < len; j++) { int b0 = b[boff + 7]; int b1 = b[boff + 6] & 0xff; int b2 = b[boff + 5] & 0xff; int b3 = b[boff + 4] & 0xff; int b4 = b[boff + 3]; int b5 = b[boff + 2] & 0xff; int b6 = b[boff + 1] & 0xff; int b7 = b[boff] & 0xff; int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; long l = ((long)i0 << 32) | (i1 & 0xffffffffL); d[off + j] = Double.longBitsToDouble(l); boff += 8; } } } public long getStreamPosition() throws IOException { checkClosed(); return streamPos; } public int getBitOffset() throws IOException { checkClosed(); return bitOffset; } public void setBitOffset(int bitOffset) throws IOException { checkClosed(); if (bitOffset < 0 || bitOffset > 7) { throw new IllegalArgumentException("bitOffset must be betwwen 0 and 7!"); } this.bitOffset = bitOffset; } public int readBit() throws IOException { checkClosed(); // Compute final bit offset before we call read() and seek() int newBitOffset = (this.bitOffset + 1) & 0x7; int val = read(); if (val == -1) { throw new EOFException(); } if (newBitOffset != 0) { // Move byte position back if in the middle of a byte seek(getStreamPosition() - 1); // Shift the bit to be read to the rightmost position val >>= 8 - newBitOffset; } this.bitOffset = newBitOffset; return val & 0x1; } public long readBits(int numBits) throws IOException { checkClosed(); if (numBits < 0 || numBits > 64) { throw new IllegalArgumentException(); } if (numBits == 0) { return 0L; } // Have to read additional bits on the left equal to the bit offset int bitsToRead = numBits + bitOffset; // Compute final bit offset before we call read() and seek() int newBitOffset = (this.bitOffset + numBits) & 0x7; // Read a byte at a time, accumulate long accum = 0L; while (bitsToRead > 0) { int val = read(); if (val == -1) { throw new EOFException(); } accum <<= 8; accum |= val; bitsToRead -= 8; } // Move byte position back if in the middle of a byte if (newBitOffset != 0) { seek(getStreamPosition() - 1); } this.bitOffset = newBitOffset; // Shift away unwanted bits on the right. accum >>>= (-bitsToRead); // Negative of bitsToRead == extra bits read // Mask out unwanted bits on the left accum &= (-1L >>> (64 - numBits)); return accum; } /** * Returns <code>-1L</code> to indicate that the stream has unknown * length. Subclasses must override this method to provide actual * length information. * * @return -1L to indicate unknown length. */ public long length() { return -1L; } /** * Advances the current stream position by calling * <code>seek(getStreamPosition() + n)</code>. * * <p> The bit offset is reset to zero. * * @param n the number of bytes to seek forward. * * @return an <code>int</code> representing the number of bytes * skipped. * * @exception IOException if <code>getStreamPosition</code> * throws an <code>IOException</code> when computing either * the starting or ending position. */ public int skipBytes(int n) throws IOException { long pos = getStreamPosition(); seek(pos + n); return (int)(getStreamPosition() - pos); } /** * Advances the current stream position by calling * <code>seek(getStreamPosition() + n)</code>. * * <p> The bit offset is reset to zero. * * @param n the number of bytes to seek forward. * * @return a <code>long</code> representing the number of bytes * skipped. * * @exception IOException if <code>getStreamPosition</code> * throws an <code>IOException</code> when computing either * the starting or ending position. */ public long skipBytes(long n) throws IOException { long pos = getStreamPosition(); seek(pos + n); return getStreamPosition() - pos; } public void seek(long pos) throws IOException { checkClosed(); // This test also covers pos < 0 if (pos < flushedPos) { throw new IndexOutOfBoundsException("pos < flushedPos!"); } this.streamPos = pos; this.bitOffset = 0; } /** * Pushes the current stream position onto a stack of marked * positions. */ public void mark() { try { markByteStack.push(Long.valueOf(getStreamPosition())); markBitStack.push(Integer.valueOf(getBitOffset())); } catch (IOException e) { } } /** * Resets the current stream byte and bit positions from the stack * of marked positions. * * <p> An <code>IOException</code> will be thrown if the previous * marked position lies in the discarded portion of the stream. * * @exception IOException if an I/O error occurs. */ public void reset() throws IOException { if (markByteStack.empty()) { return; } long pos = ((Long)markByteStack.pop()).longValue(); if (pos < flushedPos) { throw new IIOException ("Previous marked position has been discarded!"); } seek(pos); int offset = ((Integer)markBitStack.pop()).intValue(); setBitOffset(offset); } public void flushBefore(long pos) throws IOException { checkClosed(); if (pos < flushedPos) { throw new IndexOutOfBoundsException("pos < flushedPos!"); } if (pos > getStreamPosition()) { throw new IndexOutOfBoundsException("pos > getStreamPosition()!"); } // Invariant: flushedPos >= 0 flushedPos = pos; } public void flush() throws IOException { flushBefore(getStreamPosition()); } public long getFlushedPosition() { return flushedPos; } /** * Default implementation returns false. Subclasses should * override this if they cache data. */ public boolean isCached() { return false; } /** * Default implementation returns false. Subclasses should * override this if they cache data in main memory. */ public boolean isCachedMemory() { return false; } /** * Default implementation returns false. Subclasses should * override this if they cache data in a temporary file. */ public boolean isCachedFile() { return false; } public void close() throws IOException { checkClosed(); isClosed = true; } /** * Finalizes this object prior to garbage collection. The * <code>close</code> method is called to close any open input * source. This method should not be called from application * code. * * @exception Throwable if an error occurs during superclass * finalization. */ protected void finalize() throws Throwable { if (!isClosed) { try { close(); } catch (IOException e) { } } super.finalize(); } }