001: /*
002: * $RCSfile: ForwardSeekableStream.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:55:30 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.codec;
013:
014: import java.io.InputStream;
015: import java.io.IOException;
016:
017: /**
018: * A subclass of <code>SeekableStream</code> that may be used
019: * to wrap a regular <code>InputStream</code> efficiently.
020: * Seeking backwards is not supported.
021: *
022: * <p><b> This class is not a committed part of the JAI API. It may
023: * be removed or changed in future releases of JAI.</b>
024: */
025: public class ForwardSeekableStream extends SeekableStream {
026:
027: /** The source <code>InputStream</code>. */
028: private InputStream src;
029:
030: /** The current position. */
031: long pointer = 0L;
032:
033: /** The marked position. */
034: long markPos = -1L;
035:
036: /**
037: * Constructs a <code>InputStreamForwardSeekableStream</code> from a
038: * regular <code>InputStream</code>.
039: */
040: public ForwardSeekableStream(InputStream src) {
041: this .src = src;
042: }
043:
044: /** Forwards the request to the real <code>InputStream</code>. */
045: public final int read() throws IOException {
046: int result = src.read();
047: if (result != -1) {
048: ++pointer;
049: }
050: return result;
051: }
052:
053: /** Forwards the request to the real <code>InputStream</code>. */
054: public final int read(byte[] b, int off, int len)
055: throws IOException {
056: int result = src.read(b, off, len);
057: if (result != -1) {
058: pointer += result;
059: }
060: return result;
061: }
062:
063: /** Forwards the request to the real <code>InputStream</code>. */
064: public final long skip(long n) throws IOException {
065: long skipped = src.skip(n);
066: pointer += skipped;
067: return skipped;
068: }
069:
070: /** Forwards the request to the real <code>InputStream</code>. */
071: public final int available() throws IOException {
072: return src.available();
073: }
074:
075: /** Forwards the request to the real <code>InputStream</code>. */
076: public final void close() throws IOException {
077: src.close();
078: }
079:
080: /** Forwards the request to the real <code>InputStream</code>. */
081: public synchronized final void mark(int readLimit) {
082: markPos = pointer;
083: src.mark(readLimit);
084: }
085:
086: /** Forwards the request to the real <code>InputStream</code>. */
087: public synchronized final void reset() throws IOException {
088: if (markPos != -1) {
089: pointer = markPos;
090: }
091: src.reset();
092: }
093:
094: /** Forwards the request to the real <code>InputStream</code>. */
095: public boolean markSupported() {
096: return src.markSupported();
097: }
098:
099: /** Returns <code>false</code> since seking backwards is not supported. */
100: public final boolean canSeekBackwards() {
101: return false;
102: }
103:
104: /** Returns the current position in the stream (bytes read). */
105: public final long getFilePointer() {
106: return (long) pointer;
107: }
108:
109: /**
110: * Seeks forward to the given position in the stream.
111: * If <code>pos</code> is smaller than the current position
112: * as returned by <code>getFilePointer()</code>, nothing
113: * happens.
114: */
115: public final void seek(long pos) throws IOException {
116: while (pos - pointer > 0) {
117: pointer += src.skip(pos - pointer);
118: }
119: }
120: }
|