blob: 83ac13a9c986d60b492071fec438f01fb3372b58 [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.
*/
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 Signals that 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;
}
}
}