blob: d79da41859aa00502f0d9deef5a7b730ec14bbee [file] [log] [blame]
/*
* 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;
}
}
}