001: package org.columba.core.io;
002:
003: import java.io.FilterInputStream;
004: import java.io.IOException;
005: import java.io.InputStream;
006:
007: public class SteerableInputStream extends FilterInputStream {
008:
009: private long lengthLeft;
010:
011: private long position;
012:
013: public SteerableInputStream(InputStream in) {
014: super (in);
015:
016: try {
017: lengthLeft = in.available();
018: } catch (IOException e) {
019: lengthLeft = 0;
020: }
021: }
022:
023: /**
024: * {@inheritDoc}
025: */
026: @Override
027: public int read() throws IOException {
028: if (lengthLeft > 0) {
029: int read = super .read();
030: if (read != -1) {
031: lengthLeft--;
032: }
033: position++;
034: return read;
035: }
036: return -1;
037: }
038:
039: /**
040: * {@inheritDoc}
041: */
042: @Override
043: public int read(byte[] b, int off, int len) throws IOException {
044: if (len > lengthLeft) {
045: int correctedLen = (int) lengthLeft;
046: int read = super .read(b, off, correctedLen);
047: lengthLeft -= read;
048: position += read;
049: return read;
050: }
051: int read = super .read(b, off, len);
052: lengthLeft -= read;
053: position += read;
054: return read;
055:
056: }
057:
058: /**
059: * @return Returns the lengthLeft.
060: */
061: public long getLengthLeft() {
062: return lengthLeft;
063: }
064:
065: /**
066: * @param lengthLeft
067: * The lengthLeft to set.
068: */
069: public void setLengthLeft(long lengthLeft) throws IOException {
070: this .lengthLeft = Math.min(lengthLeft, in.available());
071: }
072:
073: /**
074: * @return Returns the position.
075: */
076: public long getPosition() {
077: return position;
078: }
079:
080: /**
081: * @param position
082: * The position to set.
083: */
084: public void setPosition(long newposition) throws IOException {
085: long skipped = in.skip(newposition - position);
086: lengthLeft = Math.max(0, lengthLeft - skipped);
087: position = newposition;
088: }
089:
090: /**
091: * {@inheritDoc}
092: */
093: @Override
094: public int available() throws IOException {
095: return (int) lengthLeft;
096: }
097:
098: /**
099: * {@inheritDoc}
100: */
101: @Override
102: public void close() throws IOException {
103: // do nothinh here ... use finalClose
104: }
105:
106: /**
107: * @throws IOException
108: */
109: public void finalClose() throws IOException {
110: super.close();
111: }
112:
113: }
|