--- /dev/null
+// MSFileInputStream.java\r
+// $Id: MSFileInputStream.java,v 1.1 2010/06/15 12:25:39 smhuang Exp $\r
+// (c) COPYRIGHT MIT, INRIA and Keio, 2000.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+package org.w3c.util;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.File;\r
+import java.io.FileDescriptor;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileInputStream;\r
+import java.io.FilterInputStream;\r
+\r
+/**\r
+ * @version $Revision: 1.1 $\r
+ * @author Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class MSFileInputStream extends FilterInputStream {\r
+\r
+ private File file = null;\r
+\r
+ protected int readlimit = -1;\r
+\r
+ protected int count = 0;\r
+ protected int markpos = 0;\r
+\r
+ /**\r
+ * Tests if this input stream supports the <code>mark</code> \r
+ * and <code>reset</code> methods. The <code>markSupported</code> \r
+ * method of <code>FilterInputStream</code> calls the \r
+ * <code>markSupported</code> method of its underlying input stream \r
+ * and returns whatever value that method returns. \r
+ *\r
+ * @return always true.\r
+ * @since JDK1.0\r
+ */\r
+ public boolean markSupported() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Marks the current position in this input stream. A subsequent \r
+ * call to the <code>reset</code> method repositions this stream at \r
+ * the last marked position so that subsequent reads re-read the same \r
+ * bytes. \r
+ * <p>\r
+ * The <code>readlimit</code> arguments tells this input stream to \r
+ * allow that many bytes to be read before the mark position gets \r
+ * invalidated. \r
+ * <p>\r
+ *\r
+ * @param readlimit the maximum limit of bytes that can be read before\r
+ * the mark position becomes invalid.\r
+ * @see java.io.InputStream#reset()\r
+ * @since JDK1.0\r
+ */\r
+ public synchronized void mark(int readlimit) {\r
+ this.readlimit = readlimit;\r
+ this.markpos = count;\r
+ }\r
+\r
+ /**\r
+ * Repositions this stream to the position at the time the \r
+ * <code>mark</code> method was last called on this input stream. \r
+ * <p>\r
+ * Stream marks are intended to be used in\r
+ * situations where you need to read ahead a little to see what's in\r
+ * the stream. Often this is most easily done by invoking some\r
+ * general parser. If the stream is of the type handled by the\r
+ * parser, it just chugs along happily. If the stream is not of\r
+ * that type, the parser should toss an exception when it fails,\r
+ * which, if it happens within readlimit bytes, allows the outer\r
+ * code to reset the stream and try another parser.\r
+ *\r
+ * @exception IOException if this stream has not been marked or if the\r
+ * mark has been invalidated.\r
+ * @see java.io.InputStream#mark(int)\r
+ * @see java.io.IOException\r
+ * @since JDK1.0\r
+ */\r
+ public synchronized void reset() \r
+ throws IOException \r
+ {\r
+ if (markpos < 0) {\r
+ throw new IOException("Resetting to invalid mark");\r
+ }\r
+ if (count-markpos > readlimit) {\r
+ throw new IOException("Read limit reached, invalid mark");\r
+ }\r
+ in.close();\r
+ in = new FileInputStream(file);\r
+ if (markpos > 0) {\r
+ in.skip(markpos);\r
+ }\r
+ markpos = 0;\r
+ count = 0;\r
+ }\r
+\r
+ /**\r
+ * Reads the next byte of data from this input stream. The value \r
+ * byte is returned as an <code>int</code> in the range \r
+ * <code>0</code> to <code>255</code>. If no byte is available \r
+ * because the end of the stream has been reached, the value \r
+ * <code>-1</code> is returned. This method blocks until input data \r
+ * is available, the end of the stream is detected, or an exception \r
+ * is thrown. \r
+ *\r
+ * @return the next byte of data, or <code>-1</code> if the end of the\r
+ * stream is reached.\r
+ * @exception IOException if an I/O error occurs.\r
+ * @see java.io.FilterInputStream#in\r
+ * @since JDK1.0\r
+ */\r
+ public int read() \r
+ throws IOException \r
+ {\r
+ int read = in.read();\r
+ if (read != -1) {\r
+ count++;\r
+ }\r
+ return read;\r
+ }\r
+\r
+ /**\r
+ * Reads up to <code>byte.length</code> bytes of data from this \r
+ * input stream into an array of bytes. This method blocks until some \r
+ * input is available. \r
+ *\r
+ * @param b the buffer into which the data is read.\r
+ * @return the total number of bytes read into the buffer, or\r
+ * <code>-1</code> if there is no more data because the end of\r
+ * the stream has been reached.\r
+ * @exception IOException if an I/O error occurs.\r
+ * @see java.io.FilterInputStream#read(byte[], int, int)\r
+ * @since JDK1.0\r
+ */\r
+ public int read(byte b[]) \r
+ throws IOException \r
+ {\r
+ int read = in.read(b, 0, b.length);\r
+ if (read != -1) {\r
+ count += read;\r
+ }\r
+ return read;\r
+ }\r
+\r
+ /**\r
+ * Reads up to <code>len</code> bytes of data from this input stream \r
+ * into an array of bytes. This method blocks until some input is \r
+ * available. \r
+ *\r
+ * @param b the buffer into which the data is read.\r
+ * @param off the start offset of the data.\r
+ * @param len the maximum number of bytes read.\r
+ * @return the total number of bytes read into the buffer, or\r
+ * <code>-1</code> if there is no more data because the end of\r
+ * the stream has been reached.\r
+ * @exception IOException if an I/O error occurs.\r
+ * @see java.io.FilterInputStream#in\r
+ * @since JDK1.0\r
+ */\r
+ public int read(byte b[], int off, int len) \r
+ throws IOException \r
+ {\r
+ int read = in.read(b, off, len);\r
+ if (read != -1) {\r
+ count += read;\r
+ }\r
+ return read;\r
+ }\r
+\r
+\r
+ /**\r
+ * Creates an input file stream to read from the specified file descriptor.\r
+ *\r
+ * @param fdObj the file descriptor to be opened for reading.\r
+ * @exception SecurityException if a security manager exists, its\r
+ * <code>checkRead</code> method is called with the file\r
+ * descriptor to see if the application is allowed to read\r
+ * from the specified file descriptor.\r
+ * @see java.lang.SecurityManager#checkRead(java.io.FileDescriptor)\r
+ * @since JDK1.0\r
+ */\r
+ public MSFileInputStream(File file) \r
+ throws FileNotFoundException\r
+ {\r
+ super(new FileInputStream(file));\r
+ this.file = file;\r
+ }\r
+\r
+ /**\r
+ * Creates an input file stream to read from a file with the \r
+ * specified name. \r
+ *\r
+ * @param name the system-dependent file name.\r
+ * @exception FileNotFoundException if the file is not found.\r
+ * @exception SecurityException if a security manager exists, its\r
+ * <code>checkRead</code> method is called with the name\r
+ * argument to see if the application is allowed read access\r
+ * to the file.\r
+ * @see java.lang.SecurityManager#checkRead(java.lang.String)\r
+ * @since JDK1.0\r
+ */\r
+ public MSFileInputStream(String name) \r
+ throws FileNotFoundException\r
+ {\r
+ super(new FileInputStream(name));\r
+ this.file = new File(name);\r
+ }\r
+\r
+}\r