001: package de.intarsys.tools.randomaccess;
002:
003: import java.io.IOException;
004:
005: /**
006: * A viewport in an existing {@link IRandomAccess}.
007: *
008: */
009: public class RandomAccessViewport extends RandomAccessFilter {
010:
011: private final long viewOffset;
012:
013: private long viewLength;
014:
015: private long viewEnd;
016:
017: /**
018: * Create a viewport to the existing {@link IRandomAccess} <code>ra</code>.
019: * <p>
020: * ATTENTION: This will not seek to <code>offset</code> in <code>ra</code>.
021: * This means after creation before initial use you have to position the
022: * {@link IRandomAccess} yourself using <code>seek</code>.
023: *
024: * @param ra
025: * @param offset
026: * @param length
027: * @throws IOException
028: */
029: public RandomAccessViewport(IRandomAccess ra, long offset,
030: long length) throws IOException {
031: super (ra);
032: this .viewLength = length;
033: this .viewOffset = offset;
034: this .viewEnd = viewOffset + viewLength;
035: }
036:
037: public long getLength() throws IOException {
038: long realLength = getRandom().getLength();
039: if (getViewLength() == -1) {
040: return realLength - getViewOffset();
041: }
042: return Math.min(getViewLength(), realLength - getViewOffset());
043: }
044:
045: public long getOffset() throws IOException {
046: return getRandom().getOffset() - getViewOffset();
047: }
048:
049: public boolean isReadOnly() {
050: return true;
051: }
052:
053: public int read() throws IOException {
054: if (getViewLength() != -1 && getOffset() >= getViewEnd()) {
055: return -1;
056: }
057: return super .read();
058: }
059:
060: public int read(byte[] buffer, int start, int numBytes)
061: throws IOException {
062: if (getViewLength() != -1 && getOffset() >= getViewEnd()) {
063: return -1;
064: }
065: if (getViewLength() != -1) {
066: numBytes = Math.min(numBytes,
067: (int) (getViewEnd() - getOffset()));
068: }
069: return super .read(buffer, start, numBytes);
070: }
071:
072: public int read(byte[] buffer) throws IOException {
073: return read(buffer, 0, buffer.length);
074: }
075:
076: public void seek(long offset) throws IOException {
077: super .seek(getViewOffset() + offset);
078: }
079:
080: public void seekBy(long delta) throws IOException {
081: super .seekBy(delta);
082: }
083:
084: public void setLength(long newLength) throws IOException {
085: throw new IOException("not yet supported");
086: }
087:
088: public void write(byte[] buffer, int start, int numBytes)
089: throws IOException {
090: throw new IOException("not yet supported");
091: }
092:
093: public void write(byte[] buffer) throws IOException {
094: throw new IOException("not yet supported");
095: }
096:
097: public void write(int b) throws IOException {
098: throw new IOException("not yet supported");
099: }
100:
101: protected long getViewLength() {
102: return viewLength;
103: }
104:
105: protected long getViewOffset() {
106: return viewOffset;
107: }
108:
109: protected long getViewEnd() {
110: return viewEnd;
111: }
112:
113: }
|