Commit 53a4b789 by Bryce McKinlay Committed by Bryce McKinlay

DataInputStream.java: Merge classpath docs.

2000-11-28  Bryce McKinlay  <bryce@abatross.co.nz>

	* java/io/DataInputStream.java: Merge classpath docs. Call in.read()
	directly rather than read() in all cases. Make primitive read
	implementations	more efficient, as defined in JDK online docs.
	(skipBytes): Behave like the JDK's implementation.
	* java/io/BufferedReader.java: Merge classpath docs. Check for a
	closed stream with checkStatus() whenever an IOException can be
	thrown.
	(checkStatus): New private method.

From-SVN: r37810
parent 102870fb
2000-11-28 Bryce McKinlay <bryce@abatross.co.nz>
* java/io/DataInputStream.java: Merge classpath docs. Call in.read()
directly rather than read() in all cases. Make primitive read
implementations more efficient, as defined in JDK online docs.
(skipBytes): Behave like the JDK's implementation.
* java/io/BufferedReader.java: Merge classpath docs. Check for a
closed stream with checkStatus() whenever an IOException can be
thrown.
(checkStatus): New private method.
2000-11-27 Warren Levy <warrenl@cygnus.com> 2000-11-27 Warren Levy <warrenl@cygnus.com>
* Makefile.am: Added natTimeZone.cc. * Makefile.am: Added natTimeZone.cc.
......
/* Copyright (C) 1998, 1999 Free Software Foundation /* Copyright (C) 1998, 1999, 2000 Free Software Foundation
This file is part of libgcj. This file is part of libgcj.
...@@ -8,15 +8,25 @@ details. */ ...@@ -8,15 +8,25 @@ details. */
package java.io; package java.io;
/**
* @author Per Bothner <bothner@cygnus.com>
* @date April 22, 1998.
*/
/* Written using "Java Class Libraries", 2nd edition, plus online /* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com. * API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct. * Status: Believed complete and correct.
*/ */
/**
* This subclass of <code>FilterReader</code> buffers input from an
* underlying implementation to provide a possibly more efficient read
* mechanism. It maintains the buffer and buffer state in instance
* variables that are available to subclasses. The default buffer size
* of 512 chars can be overridden by the creator of the stream.
* <p>
* This class also implements mark/reset functionality. It is capable
* of remembering any number of input chars, to the limits of
* system memory or the size of <code>Integer.MAX_VALUE</code>
*
* @author Per Bothner <bothner@cygnus.com>
* @author Aaron M. Renn <arenn@urbanophile.com>
*/
public class BufferedReader extends Reader public class BufferedReader extends Reader
{ {
Reader in; Reader in;
...@@ -43,11 +53,25 @@ public class BufferedReader extends Reader ...@@ -43,11 +53,25 @@ public class BufferedReader extends Reader
guaranteed to be >= the read-limit requested in the call to mark. */ guaranteed to be >= the read-limit requested in the call to mark. */
int markPos = -1; int markPos = -1;
/**
* Create a new <code>BufferedReader</code> that will read from the
* specified subordinate stream with a default buffer size of 4096 chars.
*
* @param in The subordinate stream to read from
*/
public BufferedReader(Reader in) public BufferedReader(Reader in)
{ {
this(in, 8192); this(in, 8192);
} }
/**
* Create a new <code>BufferedReader</code> that will read from the
* specified subordinate stream with a buffer size that is specified by the
* caller.
*
* @param in The subordinate stream to read from
* @param bufsize The buffer size to use
*/
public BufferedReader(Reader in, int size) public BufferedReader(Reader in, int size)
{ {
super(in.lock); super(in.lock);
...@@ -55,6 +79,11 @@ public class BufferedReader extends Reader ...@@ -55,6 +79,11 @@ public class BufferedReader extends Reader
buffer = new char[size]; buffer = new char[size];
} }
/**
* This method closes the stream
*
* @exception IOException If an error occurs
*/
public void close() throws IOException public void close() throws IOException
{ {
synchronized (lock) synchronized (lock)
...@@ -66,13 +95,40 @@ public class BufferedReader extends Reader ...@@ -66,13 +95,40 @@ public class BufferedReader extends Reader
} }
} }
/**
* Returns <code>true</code> to indicate that this class supports mark/reset
* functionality.
*
* @return <code>true</code>
*/
public boolean markSupported() public boolean markSupported()
{ {
return true; return true;
} }
/**
* Mark a position in the input to which the stream can be
* "reset" by calling the <code>reset()</code> method. The parameter
* <code>readlimit</code> is the number of chars that can be read from the
* stream after setting the mark before the mark becomes invalid. For
* example, if <code>mark()</code> is called with a read limit of 10, then
* when 11 chars of data are read from the stream before the
* <code>reset()</code> method is called, then the mark is invalid and the
* stream object instance is not required to remember the mark.
* <p>
* Note that the number of chars that can be remembered by this method
* can be greater than the size of the internal read buffer. It is also
* not dependent on the subordinate stream supporting mark/reset
* functionality.
*
* @param readlimit The number of chars that can be read before the mark
* becomes invalid
*
* @exception IOException If an error occurs
*/
public void mark(int readLimit) throws IOException public void mark(int readLimit) throws IOException
{ {
checkStatus();
synchronized (lock) synchronized (lock)
{ {
// In this method we need to be aware of the special case where // In this method we need to be aware of the special case where
...@@ -116,8 +172,20 @@ public class BufferedReader extends Reader ...@@ -116,8 +172,20 @@ public class BufferedReader extends Reader
} }
} }
/**
* Reset the stream to the point where the <code>mark()</code> method
* was called. Any chars that were read after the mark point was set will
* be re-read during subsequent reads.
* <p>
* This method will throw an IOException if the number of chars read from
* the stream since the call to <code>mark()</code> exceeds the mark limit
* passed when establishing the mark.
*
* @exception IOException If an error occurs;
*/
public void reset() throws IOException public void reset() throws IOException
{ {
checkStatus();
synchronized (lock) synchronized (lock)
{ {
if (markPos < 0) if (markPos < 0)
...@@ -136,16 +204,45 @@ public class BufferedReader extends Reader ...@@ -136,16 +204,45 @@ public class BufferedReader extends Reader
} }
} }
/**
* This method determines whether or not a stream is ready to be read. If
* This method returns <code>false</code> then this stream could (but is
* not guaranteed to) block on the next read attempt.
*
* @return <code>true</code> if this stream is ready to be read, <code>false</code> otherwise
*
* @exception IOException If an error occurs
*/
public boolean ready() throws IOException public boolean ready() throws IOException
{ {
checkStatus();
synchronized (lock) synchronized (lock)
{ {
return pos < limit || in.ready(); return pos < limit || in.ready();
} }
} }
/**
* This method read chars from a stream and stores them into a caller
* supplied buffer. It starts storing the data at index <code>offset</code> into
* the buffer and attempts to read <code>len</code> chars. This method can
* return before reading the number of chars requested. The actual number
* of chars read is returned as an int. A -1 is returned to indicate the
* end of the stream.
* <p>
* This method will block until some data can be read.
*
* @param buf The array into which the chars read should be stored
* @param offset The offset into the array to start storing chars
* @param count The requested number of chars to read
*
* @return The actual number of chars read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
public int read(char[] buf, int offset, int count) throws IOException public int read(char[] buf, int offset, int count) throws IOException
{ {
checkStatus();
synchronized (lock) synchronized (lock)
{ {
// Once again, we need to handle the special case of a readLine // Once again, we need to handle the special case of a readLine
...@@ -202,6 +299,7 @@ public class BufferedReader extends Reader ...@@ -202,6 +299,7 @@ public class BufferedReader extends Reader
Return number of chars read (never 0), or -1 on eof. */ Return number of chars read (never 0), or -1 on eof. */
private int fill() throws IOException private int fill() throws IOException
{ {
checkStatus();
// Handle the special case of a readLine that has a '\r' at the end of // Handle the special case of a readLine that has a '\r' at the end of
// the buffer. In this case, we'll need to skip a '\n' if it is the // the buffer. In this case, we'll need to skip a '\n' if it is the
// next char to be read. This special case is indicated by 'pos > limit'. // next char to be read. This special case is indicated by 'pos > limit'.
...@@ -228,9 +326,10 @@ public class BufferedReader extends Reader ...@@ -228,9 +326,10 @@ public class BufferedReader extends Reader
return count; return count;
} }
public int read() throws IOException public int read() throws IOException
{ {
checkStatus();
synchronized (lock) synchronized (lock)
{ {
if (pos >= limit && fill () <= 0) if (pos >= limit && fill () <= 0)
...@@ -255,8 +354,20 @@ public class BufferedReader extends Reader ...@@ -255,8 +354,20 @@ public class BufferedReader extends Reader
return i; return i;
} }
/**
* This method reads a single line of text from the input stream, returning
* it as a <code>String</code>. A line is terminated by "\n", a "\r", or
* an "\r\n" sequence. The system dependent line separator is not used.
* The line termination characters are not returned in the resulting
* <code>String</code>.
*
* @return The line of text read, or <code>null</code> if end of stream.
*
* @exception IOException If an error occurs
*/
public String readLine() throws IOException public String readLine() throws IOException
{ {
checkStatus();
// Handle the special case where a previous readLine (with no intervening // Handle the special case where a previous readLine (with no intervening
// reads/skips) had a '\r' at the end of the buffer. // reads/skips) had a '\r' at the end of the buffer.
// In this case, we'll need to skip a '\n' if it's the next char to be read. // In this case, we'll need to skip a '\n' if it's the next char to be read.
...@@ -317,8 +428,23 @@ public class BufferedReader extends Reader ...@@ -317,8 +428,23 @@ public class BufferedReader extends Reader
return (sbuf.length() == 0 && eof) ? null : sbuf.toString(); return (sbuf.length() == 0 && eof) ? null : sbuf.toString();
} }
/**
* This method skips the specified number of chars in the stream. It
* returns the actual number of chars skipped, which may be less than the
* requested amount.
* <p>
* This method first discards chars in the buffer, then calls the
* <code>skip</code> method on the underlying stream to skip the remaining chars.
*
* @param num_chars The requested number of chars to skip
*
* @return The actual number of chars skipped.
*
* @exception IOException If an error occurs
*/
public long skip(long count) throws IOException public long skip(long count) throws IOException
{ {
checkStatus();
if (count <= 0) if (count <= 0)
return 0; return 0;
synchronized (lock) synchronized (lock)
...@@ -370,4 +496,10 @@ public class BufferedReader extends Reader ...@@ -370,4 +496,10 @@ public class BufferedReader extends Reader
return count - todo; return count - todo;
} }
} }
private void checkStatus() throws IOException
{
if (in == null)
throw new IOException("Stream closed");
}
} }
...@@ -27,7 +27,6 @@ package java.io; ...@@ -27,7 +27,6 @@ package java.io;
* @author Aaron M. Renn (arenn@urbanophile.com) * @author Aaron M. Renn (arenn@urbanophile.com)
* @date October 20, 1998. * @date October 20, 1998.
*/ */
public class DataInputStream extends FilterInputStream implements DataInput public class DataInputStream extends FilterInputStream implements DataInput
{ {
// readLine() hack to ensure that an '\r' not followed by an '\n' is // readLine() hack to ensure that an '\r' not followed by an '\n' is
...@@ -61,7 +60,7 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -61,7 +60,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final int read(byte[] b) throws IOException public final int read(byte[] b) throws IOException
{ {
return super.read(b, 0, b.length); return in.read(b, 0, b.length);
} }
/** /**
...@@ -82,10 +81,7 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -82,10 +81,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final int read(byte[] b, int off, int len) throws IOException public final int read(byte[] b, int off, int len) throws IOException
{ {
if (off < 0 || len < 0 || off + len > b.length) return in.read(b, off, len);
throw new ArrayIndexOutOfBoundsException();
return super.read(b, off, len);
} }
/** /**
...@@ -106,7 +102,10 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -106,7 +102,10 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final boolean readBoolean() throws IOException public final boolean readBoolean() throws IOException
{ {
return (readByte() != 0); int b = in.read();
if (b < 0)
throw new EOFException();
return (b != 0);
} }
/** /**
...@@ -126,7 +125,7 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -126,7 +125,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final byte readByte() throws IOException public final byte readByte() throws IOException
{ {
int i = read(); int i = in.read();
if (i < 0) if (i < 0)
throw new EOFException(); throw new EOFException();
...@@ -160,7 +159,11 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -160,7 +159,11 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final char readChar() throws IOException public final char readChar() throws IOException
{ {
return (char) ((readByte() << 8) | readUnsignedByte()); int a = in.read();
int b = in.read();
if (b < 0)
throw new EOFException();
return (char) ((a << 8) | (b & 0xff));
} }
/** /**
...@@ -247,13 +250,10 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -247,13 +250,10 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final void readFully(byte[] b, int off, int len) throws IOException public final void readFully(byte[] b, int off, int len) throws IOException
{ {
if (off < 0 || len < 0 || off + len > b.length)
throw new ArrayIndexOutOfBoundsException();
while (len > 0) while (len > 0)
{ {
// super.read will block until some data is available. // in.read will block until some data is available.
int numread = super.read(b, off, len); int numread = in.read(b, off, len);
if (numread < 0) if (numread < 0)
throw new EOFException(); throw new EOFException();
len -= numread; len -= numread;
...@@ -290,11 +290,15 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -290,11 +290,15 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final int readInt() throws IOException public final int readInt() throws IOException
{ {
int retval = 0; int a = in.read();
for (int i = 0; i < 4; i++) int b = in.read();
retval |= readUnsignedByte() << (24 - i * 8); int c = in.read();
int d = in.read();
return retval; if (d < 0)
throw new EOFException();
return (((a & 0xff) << 24) | ((b & 0xff) << 16) |
((c & 0xff) << 8) | (d & 0xff));
} }
/** /**
...@@ -335,7 +339,7 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -335,7 +339,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
while (getnext) while (getnext)
{ {
getnext = false; getnext = false;
c = read(); c = in.read();
if (c < 0) // got an EOF if (c < 0) // got an EOF
return strb.length() > 0 ? strb.toString() : null; return strb.length() > 0 ? strb.toString() : null;
ch = (char) c; ch = (char) c;
...@@ -377,7 +381,7 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -377,7 +381,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
char next_ch = ' '; char next_ch = ' ';
if (in instanceof BufferedInputStream) if (in instanceof BufferedInputStream)
{ {
next_c = read(); next_c = in.read();
next_ch = (char) (next_c & 0xFF); next_ch = (char) (next_c & 0xFF);
if ((next_ch != '\n') && (next_c >= 0)) if ((next_ch != '\n') && (next_c >= 0))
{ {
...@@ -388,12 +392,12 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -388,12 +392,12 @@ public class DataInputStream extends FilterInputStream implements DataInput
} }
else if (markSupported()) else if (markSupported())
{ {
next_c = read(); next_c = in.read();
next_ch = (char) (next_c & 0xFF); next_ch = (char) (next_c & 0xFF);
if ((next_ch != '\n') && (next_c >= 0)) if ((next_ch != '\n') && (next_c >= 0))
{ {
mark(1); mark(1);
if ((read() & 0xFF) != '\n') if ((in.read() & 0xFF) != '\n')
reset(); reset();
} }
} }
...@@ -441,11 +445,25 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -441,11 +445,25 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final long readLong() throws IOException public final long readLong() throws IOException
{ {
long retval = 0L; int a = in.read();
for (int i = 0; i < 8; i++) int b = in.read();
retval |= (long) readUnsignedByte() << (56 - i * 8); int c = in.read();
int d = in.read();
return retval; int e = in.read();
int f = in.read();
int g = in.read();
int h = in.read();
if (h < 0)
throw new EOFException();
return (((long)(a & 0xff) << 56) |
((long)(b & 0xff) << 48) |
((long)(c & 0xff) << 40) |
((long)(d & 0xff) << 32) |
((long)(e & 0xff) << 24) |
((long)(f & 0xff) << 16) |
((long)(g & 0xff) << 8) |
((long)(h & 0xff)));
} }
/** /**
...@@ -477,7 +495,11 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -477,7 +495,11 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final short readShort() throws IOException public final short readShort() throws IOException
{ {
return (short) ((readByte() << 8) | readUnsignedByte()); int a = in.read();
int b = in.read();
if (b < 0)
throw new EOFException();
return (short) ((a << 8) | (b & 0xff));
} }
/** /**
...@@ -498,7 +520,7 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -498,7 +520,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final int readUnsignedByte() throws IOException public final int readUnsignedByte() throws IOException
{ {
int i = read(); int i = in.read();
if (i < 0) if (i < 0)
throw new EOFException(); throw new EOFException();
...@@ -532,7 +554,11 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -532,7 +554,11 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/ */
public final int readUnsignedShort() throws IOException public final int readUnsignedShort() throws IOException
{ {
return (readUnsignedByte() << 8) | readUnsignedByte(); int a = in.read();
int b = in.read();
if (b < 0)
throw new EOFException();
return (((a & 0xff) << 8) | (b & 0xff));
} }
/** /**
...@@ -664,34 +690,29 @@ public class DataInputStream extends FilterInputStream implements DataInput ...@@ -664,34 +690,29 @@ public class DataInputStream extends FilterInputStream implements DataInput
/** /**
* This method attempts to skip and discard the specified number of bytes * This method attempts to skip and discard the specified number of bytes
* in the input stream. It may actually skip fewer bytes than requested. * in the input stream. It may actually skip fewer bytes than requested.
* The actual number of bytes skipped is returned. This method will not * This method will not skip any bytes if passed a negative number of bytes
* skip any bytes if passed a negative number of bytes to skip. * to skip.
* *
* @param n The requested number of bytes to skip. * @param n The requested number of bytes to skip.
* * @return The requested number of bytes to skip.
* @return The number of bytes actually skipped.
*
* @exception IOException If an error occurs. * @exception IOException If an error occurs.
* @specnote The JDK docs claim that this returns the number of bytes
* actually skipped. The JCL claims that this method can throw an
* EOFException. Neither of these appear to be true in the JDK 1.3's
* implementation. This tries to implement the actual JDK behaviour.
*/ */
public final int skipBytes(int n) throws IOException public final int skipBytes(int n) throws IOException
{ {
// The contract in the Java Lang. Spec. says that this never if (n <= 0)
// throws an EOFException and infers that it doesn't block (since return 0;
// it may skip less than the requested number of bytes). try
// BUT, the JCL book specifically says that this method blocks
// and can throw an EOFException. Finally, the Java 1.2 online
// doc simply refers to the general contract. As such, we will
// stick to the contract and assume for now that the JCL book
// is incorrect.
// Since we're only skipping at most an int number of bytes, the cast
// of return value to an int is fine.
if (n > 0)
{ {
n = Math.min(n, available()); return (int) in.skip(n);
return (int) super.skip((long) n);
} }
catch (EOFException x)
return 0; {
// do nothing.
}
return n;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment