| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| /** |
| * @author Rustem V. Rafikov |
| * @version $Revision: 1.3 $ |
| */ |
| |
| package javax.imageio.stream; |
| |
| import java.io.EOFException; |
| import java.io.IOException; |
| import java.nio.ByteOrder; |
| |
| /** |
| * The ImageInputStreamImpl abstract class implements the ImageInputStream |
| * interface. |
| * |
| * @since Android 1.0 |
| */ |
| public abstract class ImageInputStreamImpl implements ImageInputStream { |
| |
| /** |
| * The byte order. |
| */ |
| protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN; |
| |
| /** |
| * The stream position. |
| */ |
| protected long streamPos = 0; |
| |
| /** |
| * The flushed position. |
| */ |
| protected long flushedPos = 0; |
| |
| /** |
| * The bit offset. |
| */ |
| protected int bitOffset = 0; |
| |
| /** |
| * The closed. |
| */ |
| private boolean closed = false; |
| |
| /** |
| * The position stack. |
| */ |
| private final PositionStack posStack = new PositionStack(); |
| |
| /** |
| * Instantiates a new ImageInputStreamImpl. |
| */ |
| public ImageInputStreamImpl() { |
| } |
| |
| /** |
| * Check if the stream is closed and if true, throws an IOException. |
| * |
| * @throws IOException |
| * if the stream is closed. |
| */ |
| protected final void checkClosed() throws IOException { |
| if (closed) { |
| throw new IOException("stream is closed"); |
| } |
| } |
| |
| public void setByteOrder(ByteOrder byteOrder) { |
| this.byteOrder = byteOrder; |
| } |
| |
| public ByteOrder getByteOrder() { |
| return byteOrder; |
| } |
| |
| public abstract int read() throws IOException; |
| |
| public int read(byte[] b) throws IOException { |
| return read(b, 0, b.length); |
| } |
| |
| public abstract int read(byte[] b, int off, int len) throws IOException; |
| |
| public void readBytes(IIOByteBuffer buf, int len) throws IOException { |
| if (buf == null) { |
| throw new NullPointerException("buffer is NULL"); |
| } |
| |
| byte[] b = new byte[len]; |
| len = read(b, 0, b.length); |
| |
| buf.setData(b); |
| buf.setOffset(0); |
| buf.setLength(len); |
| } |
| |
| public boolean readBoolean() throws IOException { |
| int b = read(); |
| if (b < 0) { |
| throw new EOFException("EOF reached"); |
| } |
| return b != 0; |
| } |
| |
| public byte readByte() throws IOException { |
| int b = read(); |
| if (b < 0) { |
| throw new EOFException("EOF reached"); |
| } |
| return (byte)b; |
| } |
| |
| public int readUnsignedByte() throws IOException { |
| int b = read(); |
| if (b < 0) { |
| throw new EOFException("EOF reached"); |
| } |
| return b; |
| } |
| |
| public short readShort() throws IOException { |
| int b1 = read(); |
| int b2 = read(); |
| |
| if (b1 < 0 || b2 < 0) { |
| throw new EOFException("EOF reached"); |
| } |
| |
| return byteOrder == ByteOrder.BIG_ENDIAN ? (short)((b1 << 8) | (b2 & 0xff)) |
| : (short)((b2 << 8) | (b1 & 0xff)); |
| } |
| |
| public int readUnsignedShort() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public char readChar() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public int readInt() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public long readUnsignedInt() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public long readLong() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public float readFloat() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public double readDouble() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public String readLine() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public String readUTF() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void readFully(byte[] b, int off, int len) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void readFully(byte[] b) throws IOException { |
| readFully(b, 0, b.length); |
| } |
| |
| public void readFully(short[] s, int off, int len) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void readFully(char[] c, int off, int len) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void readFully(int[] i, int off, int len) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void readFully(long[] l, int off, int len) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void readFully(float[] f, int off, int len) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void readFully(double[] d, int off, int len) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public long getStreamPosition() throws IOException { |
| checkClosed(); |
| return streamPos; |
| } |
| |
| public int getBitOffset() throws IOException { |
| checkClosed(); |
| return bitOffset; |
| } |
| |
| public void setBitOffset(int bitOffset) throws IOException { |
| checkClosed(); |
| this.bitOffset = bitOffset; |
| } |
| |
| public int readBit() throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public long readBits(int numBits) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public long length() { |
| return -1L; |
| } |
| |
| public int skipBytes(int n) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public long skipBytes(long n) throws IOException { |
| // -- TODO implement |
| throw new UnsupportedOperationException("Not implemented yet"); |
| } |
| |
| public void seek(long pos) throws IOException { |
| checkClosed(); |
| if (pos < getFlushedPosition()) { |
| throw new IllegalArgumentException("trying to seek before flushed pos"); |
| } |
| bitOffset = 0; |
| streamPos = pos; |
| } |
| |
| public void mark() { |
| try { |
| posStack.push(getStreamPosition()); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| throw new RuntimeException("Stream marking error"); |
| } |
| } |
| |
| public void reset() throws IOException { |
| // -- TODO bit pos |
| if (!posStack.isEmpty()) { |
| long p = posStack.pop(); |
| if (p < flushedPos) { |
| throw new IOException("marked position lies in the flushed portion of the stream"); |
| } |
| seek(p); |
| } |
| } |
| |
| public void flushBefore(long pos) throws IOException { |
| if (pos > getStreamPosition()) { |
| throw new IndexOutOfBoundsException("Trying to flush outside of current position"); |
| } |
| if (pos < flushedPos) { |
| throw new IndexOutOfBoundsException("Trying to flush within already flushed portion"); |
| } |
| flushedPos = pos; |
| // -- TODO implement |
| } |
| |
| public void flush() throws IOException { |
| flushBefore(getStreamPosition()); |
| } |
| |
| public long getFlushedPosition() { |
| return flushedPos; |
| } |
| |
| public boolean isCached() { |
| return false; // def |
| } |
| |
| public boolean isCachedMemory() { |
| return false; // def |
| } |
| |
| public boolean isCachedFile() { |
| return false; // def |
| } |
| |
| public void close() throws IOException { |
| checkClosed(); |
| closed = true; |
| |
| } |
| |
| /** |
| * Finalizes this object. |
| * |
| * @throws Throwable |
| * if an error occurs. |
| */ |
| @Override |
| protected void finalize() throws Throwable { |
| if (!closed) { |
| try { |
| close(); |
| } finally { |
| super.finalize(); |
| } |
| } |
| } |
| |
| /** |
| * The Class PositionStack. |
| */ |
| private static class PositionStack { |
| |
| /** |
| * The Constant SIZE. |
| */ |
| private static final int SIZE = 10; |
| |
| /** |
| * The values. |
| */ |
| private long[] values = new long[SIZE]; |
| |
| /** |
| * The pos. |
| */ |
| private int pos = 0; |
| |
| /** |
| * Push. |
| * |
| * @param v |
| * the v. |
| */ |
| void push(long v) { |
| if (pos >= values.length) { |
| ensure(pos + 1); |
| } |
| values[pos++] = v; |
| } |
| |
| /** |
| * Pop. |
| * |
| * @return the long. |
| */ |
| long pop() { |
| return values[--pos]; |
| } |
| |
| /** |
| * Checks if is empty. |
| * |
| * @return true, if is empty. |
| */ |
| boolean isEmpty() { |
| return pos == 0; |
| } |
| |
| /** |
| * Ensure. |
| * |
| * @param size |
| * the size. |
| */ |
| private void ensure(int size) { |
| long[] arr = new long[Math.max(2 * values.length, size)]; |
| System.arraycopy(values, 0, arr, 0, values.length); |
| values = arr; |
| } |
| } |
| } |