001: // MSFileInputStream.java
002: // $Id: MSFileInputStream.java,v 1.2 2000/08/16 21:37:58 ylafon Exp $
003: // (c) COPYRIGHT MIT, INRIA and Keio, 2000.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005: package org.w3c.util;
006:
007: import java.io.IOException;
008: import java.io.InputStream;
009: import java.io.File;
010: import java.io.FileDescriptor;
011: import java.io.FileNotFoundException;
012: import java.io.FileInputStream;
013: import java.io.FilterInputStream;
014:
015: /**
016: * @version $Revision: 1.2 $
017: * @author Benoît Mahé (bmahe@w3.org)
018: */
019: public class MSFileInputStream extends FilterInputStream {
020:
021: private File file = null;
022:
023: protected int readlimit = -1;
024:
025: protected int count = 0;
026: protected int markpos = 0;
027:
028: /**
029: * Tests if this input stream supports the <code>mark</code>
030: * and <code>reset</code> methods. The <code>markSupported</code>
031: * method of <code>FilterInputStream</code> calls the
032: * <code>markSupported</code> method of its underlying input stream
033: * and returns whatever value that method returns.
034: *
035: * @return always true.
036: * @since JDK1.0
037: */
038: public boolean markSupported() {
039: return true;
040: }
041:
042: /**
043: * Marks the current position in this input stream. A subsequent
044: * call to the <code>reset</code> method repositions this stream at
045: * the last marked position so that subsequent reads re-read the same
046: * bytes.
047: * <p>
048: * The <code>readlimit</code> arguments tells this input stream to
049: * allow that many bytes to be read before the mark position gets
050: * invalidated.
051: * <p>
052: *
053: * @param readlimit the maximum limit of bytes that can be read before
054: * the mark position becomes invalid.
055: * @see java.io.InputStream#reset()
056: * @since JDK1.0
057: */
058: public synchronized void mark(int readlimit) {
059: this .readlimit = readlimit;
060: this .markpos = count;
061: }
062:
063: /**
064: * Repositions this stream to the position at the time the
065: * <code>mark</code> method was last called on this input stream.
066: * <p>
067: * Stream marks are intended to be used in
068: * situations where you need to read ahead a little to see what's in
069: * the stream. Often this is most easily done by invoking some
070: * general parser. If the stream is of the type handled by the
071: * parser, it just chugs along happily. If the stream is not of
072: * that type, the parser should toss an exception when it fails,
073: * which, if it happens within readlimit bytes, allows the outer
074: * code to reset the stream and try another parser.
075: *
076: * @exception IOException if this stream has not been marked or if the
077: * mark has been invalidated.
078: * @see java.io.InputStream#mark(int)
079: * @see java.io.IOException
080: * @since JDK1.0
081: */
082: public synchronized void reset() throws IOException {
083: if (markpos < 0) {
084: throw new IOException("Resetting to invalid mark");
085: }
086: if (count - markpos > readlimit) {
087: throw new IOException("Read limit reached, invalid mark");
088: }
089: in.close();
090: in = new FileInputStream(file);
091: if (markpos > 0) {
092: in.skip(markpos);
093: }
094: markpos = 0;
095: count = 0;
096: }
097:
098: /**
099: * Reads the next byte of data from this input stream. The value
100: * byte is returned as an <code>int</code> in the range
101: * <code>0</code> to <code>255</code>. If no byte is available
102: * because the end of the stream has been reached, the value
103: * <code>-1</code> is returned. This method blocks until input data
104: * is available, the end of the stream is detected, or an exception
105: * is thrown.
106: *
107: * @return the next byte of data, or <code>-1</code> if the end of the
108: * stream is reached.
109: * @exception IOException if an I/O error occurs.
110: * @see java.io.FilterInputStream#in
111: * @since JDK1.0
112: */
113: public int read() throws IOException {
114: int read = in.read();
115: if (read != -1) {
116: count++;
117: }
118: return read;
119: }
120:
121: /**
122: * Reads up to <code>byte.length</code> bytes of data from this
123: * input stream into an array of bytes. This method blocks until some
124: * input is available.
125: *
126: * @param b the buffer into which the data is read.
127: * @return the total number of bytes read into the buffer, or
128: * <code>-1</code> if there is no more data because the end of
129: * the stream has been reached.
130: * @exception IOException if an I/O error occurs.
131: * @see java.io.FilterInputStream#read(byte[], int, int)
132: * @since JDK1.0
133: */
134: public int read(byte b[]) throws IOException {
135: int read = in.read(b, 0, b.length);
136: if (read != -1) {
137: count += read;
138: }
139: return read;
140: }
141:
142: /**
143: * Reads up to <code>len</code> bytes of data from this input stream
144: * into an array of bytes. This method blocks until some input is
145: * available.
146: *
147: * @param b the buffer into which the data is read.
148: * @param off the start offset of the data.
149: * @param len the maximum number of bytes read.
150: * @return the total number of bytes read into the buffer, or
151: * <code>-1</code> if there is no more data because the end of
152: * the stream has been reached.
153: * @exception IOException if an I/O error occurs.
154: * @see java.io.FilterInputStream#in
155: * @since JDK1.0
156: */
157: public int read(byte b[], int off, int len) throws IOException {
158: int read = in.read(b, off, len);
159: if (read != -1) {
160: count += read;
161: }
162: return read;
163: }
164:
165: /**
166: * Creates an input file stream to read from the specified file descriptor.
167: *
168: * @param fdObj the file descriptor to be opened for reading.
169: * @exception SecurityException if a security manager exists, its
170: * <code>checkRead</code> method is called with the file
171: * descriptor to see if the application is allowed to read
172: * from the specified file descriptor.
173: * @see java.lang.SecurityManager#checkRead(java.io.FileDescriptor)
174: * @since JDK1.0
175: */
176: public MSFileInputStream(File file) throws FileNotFoundException {
177: super (new FileInputStream(file));
178: this .file = file;
179: }
180:
181: /**
182: * Creates an input file stream to read from a file with the
183: * specified name.
184: *
185: * @param name the system-dependent file name.
186: * @exception FileNotFoundException if the file is not found.
187: * @exception SecurityException if a security manager exists, its
188: * <code>checkRead</code> method is called with the name
189: * argument to see if the application is allowed read access
190: * to the file.
191: * @see java.lang.SecurityManager#checkRead(java.lang.String)
192: * @since JDK1.0
193: */
194: public MSFileInputStream(String name) throws FileNotFoundException {
195: super (new FileInputStream(name));
196: this .file = new File(name);
197: }
198:
199: }
|