/libjava/classpath/javax/imageio/stream/ImageInputStreamImpl.java
Java | 542 lines | 399 code | 94 blank | 49 comment | 39 complexity | 204dc156ce648a9cbb63a4aa240a9aa6 MD5 | raw file
- /* ImageInputStream.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath 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, or (at your option)
- any later version.
- GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package javax.imageio.stream;
- import gnu.java.lang.CPStringBuilder;
- import java.io.DataInputStream;
- import java.io.EOFException;
- import java.io.IOException;
- import java.nio.ByteOrder;
- import java.util.Stack;
- /**
- * @author Michael Koch (konqueror@gmx.de)
- */
- public abstract class ImageInputStreamImpl implements ImageInputStream
- {
- private boolean closed;
- private Stack markStack = new Stack();
- byte[] buffer = new byte[8];
- protected int bitOffset;
- protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
- protected long flushedPos;
- protected long streamPos;
- public ImageInputStreamImpl()
- {
- // Do nothing here.
- }
- protected final void checkClosed()
- throws IOException
- {
- if (closed)
- throw new IOException("stream closed");
- }
- public void close()
- throws IOException
- {
- checkClosed();
- closed = true;
- }
- protected void finalize()
- throws Throwable
- {
- if (!closed)
- close();
- }
- public void flush()
- throws IOException
- {
- flushBefore(getStreamPosition());
- }
- public void flushBefore(long position)
- throws IOException
- {
- if (position < flushedPos)
- throw new IndexOutOfBoundsException();
- if (position > streamPos)
- throw new IndexOutOfBoundsException();
- flushedPos = position;
- }
- public int getBitOffset()
- throws IOException
- {
- checkClosed();
- return bitOffset;
- }
- public ByteOrder getByteOrder()
- {
- return byteOrder;
- }
- public long getFlushedPosition()
- {
- return flushedPos;
- }
- public long getStreamPosition()
- throws IOException
- {
- checkClosed();
- return streamPos;
- }
- public boolean isCached()
- {
- return false;
- }
- public boolean isCachedFile()
- {
- return false;
- }
- public boolean isCachedMemory()
- {
- return false;
- }
- public long length()
- {
- return -1L;
- }
- public void mark()
- {
- try
- {
- markStack.push(new Long(getStreamPosition()));
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
- }
- }
- public abstract int read()
- throws IOException;
- public abstract int read(byte[] data, int offset, int len)
- throws IOException;
- public int read(byte[] data)
- throws IOException
- {
- return read(data, 0, data.length);
- }
- public int readBit()
- throws IOException
- {
- checkClosed();
- // Calculate new bit offset here as readByte clears it.
- int newOffset = (bitOffset + 1) & 0x7;
- // Clears bitOffset.
- byte data = readByte();
- // If newOffset is 0 it means we just read the 8th bit in a byte
- // and therefore we want to advance to the next byte. Otherwise
- // we want to roll back the stream one byte so that future readBit
- // calls read bits from the same current byte.
- if (newOffset != 0)
- {
- seek(getStreamPosition() - 1);
- data = (byte) (data >> (8 - newOffset));
- }
- bitOffset = newOffset;
- return data & 0x1;
- }
- public long readBits(int numBits)
- throws IOException
- {
- checkClosed();
- if (numBits < 0 || numBits > 64)
- throw new IllegalArgumentException();
- long bits = 0L;
- for (int i = 0; i < numBits; i++)
- {
- bits <<= 1;
- bits |= readBit();
- }
- return bits;
- }
- public boolean readBoolean()
- throws IOException
- {
- byte data = readByte();
- return data != 0;
- }
- public byte readByte()
- throws IOException
- {
- checkClosed();
- int data = read();
- if (data == -1)
- throw new EOFException();
- return (byte) data;
- }
- public void readBytes(IIOByteBuffer buffer, int len)
- throws IOException
- {
- readFullyPrivate(buffer.getData(), buffer.getOffset(), len);
- buffer.setLength(len);
- }
- public char readChar()
- throws IOException
- {
- return (char) readShort();
- }
- public double readDouble()
- throws IOException
- {
- return Double.longBitsToDouble(readLong());
- }
- public float readFloat()
- throws IOException
- {
- return Float.intBitsToFloat(readInt());
- }
- public void readFully(byte[] data)
- throws IOException
- {
- readFully(data, 0, data.length);
- }
- public void readFully(byte[] data, int offset, int len)
- throws IOException
- {
- readFullyPrivate(data, offset, len);
- }
- public void readFully(char[] data, int offset, int len)
- throws IOException
- {
- for (int i = 0; i < len; ++i)
- data[offset + i] = readChar();
- }
- public void readFully(double[] data, int offset, int len)
- throws IOException
- {
- for (int i = 0; i < len; ++i)
- data[offset + i] = readDouble();
- }
- public void readFully(float[] data, int offset, int len)
- throws IOException
- {
- for (int i = 0; i < len; ++i)
- data[offset + i] = readFloat();
- }
- public void readFully(int[] data, int offset, int len)
- throws IOException
- {
- for (int i = 0; i < len; ++i)
- data[offset + i] = readInt();
- }
- public void readFully(long[] data, int offset, int len)
- throws IOException
- {
- for (int i = 0; i < len; ++i)
- data[offset + i] = readLong();
- }
- public void readFully(short[] data, int offset, int len)
- throws IOException
- {
- for (int i = 0; i < len; ++i)
- data[offset + i] = readShort();
- }
- public int readInt()
- throws IOException
- {
- readFullyPrivate(buffer, 0, 4);
- if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
- return (int)
- (((int) (buffer[0] & 0xff) << 0)
- | ((int) (buffer[1] & 0xff) << 8)
- | ((int) (buffer[2] & 0xff) << 16)
- | ((int) (buffer[3] & 0xff) << 24));
- return (int)
- (((int) (buffer[0] & 0xff) << 24)
- + ((int) (buffer[1] & 0xff) << 16)
- + ((int) (buffer[2] & 0xff) << 8)
- + ((int) (buffer[3] & 0xff) << 0));
- }
- public String readLine()
- throws IOException
- {
- checkClosed();
- int c = -1;
- boolean eol = false;
- CPStringBuilder buffer = new CPStringBuilder();
- c = read();
- if (c == -1)
- return null;
- while (!eol)
- {
- switch(c)
- {
- case '\r':
- // Check for following '\n'.
- long oldPosition = getStreamPosition();
- c = read();
- if (c == -1 || c == '\n')
- eol = true;
- else
- {
- seek(oldPosition);
- eol = true;
- }
- continue;
- case '\n':
- eol = true;
- continue;
- default:
- buffer.append((char) c);
- break;
- }
- c = read();
- if (c == -1)
- eol = true;
- }
- return buffer.toString();
- }
- public long readLong()
- throws IOException
- {
- readFullyPrivate(buffer, 0, 8);
- if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
- return (long)
- (((long) (buffer[0] & 0xff) << 0)
- | ((long) (buffer[1] & 0xff) << 8)
- | ((long) (buffer[2] & 0xff) << 16)
- | ((long) (buffer[3] & 0xff) << 24)
- | ((long) (buffer[4] & 0xff) << 32)
- | ((long) (buffer[5] & 0xff) << 40)
- | ((long) (buffer[6] & 0xff) << 48)
- | ((long) (buffer[7] & 0xff) << 56));
- return (long)
- (((long) (buffer[0] & 0xff) << 56)
- | ((long) (buffer[1] & 0xff) << 48)
- | ((long) (buffer[2] & 0xff) << 40)
- | ((long) (buffer[3] & 0xff) << 32)
- | ((long) (buffer[4] & 0xff) << 24)
- | ((long) (buffer[5] & 0xff) << 16)
- | ((long) (buffer[6] & 0xff) << 8)
- | ((long) (buffer[7] & 0xff) << 0));
- }
- public short readShort()
- throws IOException
- {
- readFullyPrivate(buffer, 0, 2);
- if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
- return (short)
- (((short) (buffer[0] & 0xff) << 0)
- | ((short) (buffer[1] & 0xff) << 8));
- return (short)
- (((short) (buffer[0] & 0xff) << 8)
- | ((short) (buffer[1] & 0xff) << 0));
- }
- public int readUnsignedByte()
- throws IOException
- {
- return (int) readByte() & 0xff;
- }
- public long readUnsignedInt()
- throws IOException
- {
- return (long) readInt() & 0xffffffffL;
- }
- public int readUnsignedShort()
- throws IOException
- {
- return (int) readShort() & 0xffff;
- }
- public String readUTF()
- throws IOException
- {
- checkClosed();
- String data;
- ByteOrder old = getByteOrder();
- // Strings are always big endian.
- setByteOrder(ByteOrder.BIG_ENDIAN);
- try
- {
- data = DataInputStream.readUTF(this);
- }
- finally
- {
- setByteOrder(old);
- }
- return data;
- }
- public void reset()
- throws IOException
- {
- checkClosed();
- long mark = ((Long) markStack.pop()).longValue();
- seek(mark);
- }
- public void seek(long position)
- throws IOException
- {
- checkClosed();
- if (position < getFlushedPosition())
- throw new IndexOutOfBoundsException("position < flushed position");
- streamPos = position;
- bitOffset = 0;
- }
- public void setBitOffset (int bitOffset)
- throws IOException
- {
- checkClosed();
- if (bitOffset < 0 || bitOffset > 7)
- throw new IllegalArgumentException("bitOffset not between 0 and 7 inclusive");
- this.bitOffset = bitOffset;
- }
- public void setByteOrder(ByteOrder byteOrder)
- {
- this.byteOrder = byteOrder;
- }
- public int skipBytes(int num)
- throws IOException
- {
- checkClosed();
- seek(getStreamPosition() + num);
- bitOffset = 0;
- return num;
- }
- public long skipBytes(long num)
- throws IOException
- {
- checkClosed();
- seek(getStreamPosition() + num);
- bitOffset = 0;
- return num;
- }
- private void readFullyPrivate (byte[] buf, int offset, int len) throws IOException
- {
- checkClosed();
- if (len < 0)
- throw new IndexOutOfBoundsException("Negative length: " + len);
- while (len > 0)
- {
- // read will block until some data is available.
- int numread = read (buf, offset, len);
- if (numread < 0)
- throw new EOFException ();
- len -= numread;
- offset += numread;
- }
- bitOffset = 0;
- }
- }