Chris@2: /* Chris@2: Copyright (C) 2001, 2006 by Simon Dixon Chris@2: Chris@2: This program is free software; you can redistribute it and/or modify Chris@2: it under the terms of the GNU General Public License as published by Chris@2: the Free Software Foundation; either version 2 of the License, or Chris@2: (at your option) any later version. Chris@2: Chris@2: This program is distributed in the hope that it will be useful, Chris@2: but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@2: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@2: GNU General Public License for more details. Chris@2: Chris@2: You should have received a copy of the GNU General Public License along Chris@2: with this program (the file gpl.txt); if not, download it from Chris@2: http://www.gnu.org/licenses/gpl.txt or write to the Chris@2: Free Software Foundation, Inc., Chris@2: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Chris@2: */ Chris@2: Chris@2: package at.ofai.music.util; Chris@2: import java.io.*; Chris@2: Chris@2: public class RandomAccessInputStream extends InputStream { Chris@2: Chris@2: protected RandomAccessFile r; Chris@2: protected long markPosition = 0; Chris@2: Chris@2: public RandomAccessInputStream(String name) throws FileNotFoundException { Chris@2: r = new RandomAccessFile(name, "r"); Chris@2: } // constructor Chris@2: Chris@2: public RandomAccessInputStream(File f) throws FileNotFoundException { Chris@2: r = new RandomAccessFile(f, "r"); Chris@2: } // constructor Chris@2: Chris@2: /** Returns the number of bytes that can be read (or skipped over) from Chris@2: * this input stream without blocking by the next caller of a method for Chris@2: * this input stream. Chris@2: */ Chris@2: public int available() throws IOException { Chris@2: long availableBytes = r.length() - r.getFilePointer(); Chris@2: if (availableBytes > Integer.MAX_VALUE) Chris@2: return Integer.MAX_VALUE; Chris@2: else Chris@2: return (int)availableBytes; Chris@2: } // available() Chris@2: Chris@2: /** Closes this input stream and releases any system resources associated Chris@2: * with the stream. Chris@2: */ Chris@2: public void close() throws IOException { Chris@2: r.close(); Chris@2: } // close() Chris@2: Chris@2: /** Marks the current position in this input stream. Chris@2: * Warning: Use mark() instead of mark(int). Chris@2: * IOExceptions are caught, because InputStream doesn't allow them to be Chris@2: * thrown. The exception is printed and the mark position invalidated. Chris@2: * @param readlimit Ignored Chris@2: */ Chris@2: public void mark(int readlimit) { Chris@2: try { Chris@2: mark(); Chris@2: } catch (IOException e) { Chris@2: e.printStackTrace(); Chris@2: markPosition = -1; Chris@2: } Chris@2: } // mark() Chris@2: Chris@2: /** Marks the current position in this input stream. Chris@2: */ Chris@2: public void mark() throws IOException { Chris@2: markPosition = r.getFilePointer(); Chris@2: } // mark() Chris@2: Chris@2: /** This input stream supports the mark and reset methods. Chris@2: * @return true Chris@2: */ Chris@2: public boolean markSupported() { Chris@2: return true; Chris@2: } // markSupported() Chris@2: Chris@2: /** Reads the next byte of data from the input stream. Chris@2: */ Chris@2: public int read() throws IOException { Chris@2: return r.read(); Chris@2: } // read() Chris@2: Chris@2: /** Reads some number of bytes from the input stream and stores them into Chris@2: * the buffer array b. Chris@2: */ Chris@2: public int read(byte[] b) throws IOException { Chris@2: return r.read(b); Chris@2: } // read() Chris@2: Chris@2: /** Reads up to len bytes of data from the input stream into an array of Chris@2: * bytes. Chris@2: */ Chris@2: public int read(byte[] b, int off, int len) throws IOException { Chris@2: return r.read(b, off, len); Chris@2: } // read() Chris@2: Chris@2: /** Repositions this stream to the position at the time the mark method Chris@2: * was last called on this input stream. Chris@2: */ Chris@2: public void reset() throws IOException { Chris@2: if (markPosition < 0) Chris@2: throw new IOException("reset(): invalid mark position"); Chris@2: r.seek(markPosition); Chris@2: } // reset() Chris@2: Chris@2: /** Skips over and discards n bytes of data from this input stream. Chris@2: */ Chris@2: public long skip(long n) throws IOException { Chris@2: long pos = r.getFilePointer(); Chris@2: r.seek(n + pos); Chris@2: return r.getFilePointer() - pos; Chris@2: } // skip() Chris@2: Chris@2: /** Seek to a position n bytes after the mark. Chris@2: */ Chris@2: public long seekFromMark(long n) throws IOException { Chris@2: r.seek(markPosition + n); Chris@2: return r.getFilePointer() - markPosition; Chris@2: } // seekFromMark() Chris@2: Chris@2: } // class RandomAccessInputStream