/* * @(#)DataInputStream.java 1.37 97/02/27 * * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * * CopyrightVersion 1.1_beta * */ package java.io; /** * A data input stream lets an application read primitive Java data * types from an underlying input stream in a machine-independent * way. An application uses a data output stream to write data that * can later be read by a data input stream. *
* Data input streams and data output streams represent Unicode * strings in a format that is a slight modification of UTF-8. (For * more information, see X/Open Company Ltd., "File System Safe * UCS Transformation Format (FSS_UTF)", X/Open Preliminary * Specification, Document Number: P316. This information also * appears in ISO/IEC 10646, Annex P.) *
* All characters in the range '\u0001'
to
* '\u007F'
are represented by a single byte:
*
0 | bits 0-7 |
* The null character '\u0000'
and characters in the
* range '\u0080'
to '\u07FF'
are
* represented by a pair of bytes:
*
1 | 1 | 0 | bits 6-10 |
1 | 0 | bits 0-5 |
'\u0800'
to
* '\uFFFF'
are represented by three bytes:
* 1 | 1 | 1 | 0 | bits 12-15 | *
1 | 0 | bits 6-11 | ||
1 | 0 | bits 0-5 |
* The two differences between this format and the * "standard" UTF-8 format are the following: *
'\u0000'
is encoded in 2-byte format
* rather than 1-byte, so that the encoded strings never have
* embedded nulls.
* byte.length
bytes of data from this data
* input stream into an array of bytes. This method blocks until some
* input is available.
*
* The read
method of DataInputStream
* calls the read
method of its underlying input stream
* with the three arguments b
, 0
, and
* b.length
and returns whatever value that method returns.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* -1
if there is no more data because the end
* of the stream has been reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.InputStream#read(byte[], int, int)
*/
public final int read(byte b[]) throws IOException {
return in.read(b, 0, b.length);
}
/**
* Reads up to len
bytes of data from this data input
* stream into an array of bytes. This method blocks until some input
* is available.
*
* The read
method of DataInputStream
* calls the read
method of its underlying input stream
* with the same arguments and returns whatever value that method returns.
*
* @param b the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* -1
if there is no more data because the end
* of the stream has been reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
* @see java.io.InputStream#read(byte[], int, int)
*/
public final int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
/**
* Reads b.length
bytes from this data input stream
* into the byte array. This method reads repeatedly from the
* underlying stream until all the bytes are read. This method blocks
* until all the bytes are read, the end of the stream is detected,
* or an exception is thrown.
*
* @param b the buffer into which the data is read.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final void readFully(byte b[]) throws IOException {
readFully(b, 0, b.length);
}
/**
* Reads exactly len
bytes from this data input stream
* into the byte array. This method reads repeatedly from the
* underlying stream until all the bytes are read. This method blocks
* until all the bytes are read, the end of the stream is detected,
* or an exception is thrown.
*
* @param b the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the number of bytes to read.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final void readFully(byte b[], int off, int len) throws IOException {
InputStream in = this.in;
int n = 0;
while (n < len) {
int count = in.read(b, off + n, len - n);
if (count < 0)
throw new EOFException();
n += count;
}
}
/**
* Skips exactly n
bytes of input in the underlying
* input stream. This method blocks until all the bytes are skipped,
* the end of the stream is detected, or an exception is thrown.
*
* @param n the number of bytes to be skipped.
* @return the number of bytes skipped, which is always n
.
* @exception EOFException if this input stream reaches the end before
* skipping all the bytes.
* @exception IOException if an I/O error occurs.
*/
public final int skipBytes(int n) throws IOException {
InputStream in = this.in;
for (int i = 0 ; i < n ; i += (int)in.skip(n - i));
return n;
}
/**
* Reads a boolean
from this data input stream. This
* method reads a single byte from the underlying input stream. A
* value of 0
represents false
. Any other
* value represents true
. This method blocks until
* either the byte is read, the end of the stream is detected, or an
* exception is thrown.
*
* @return the boolean
value read.
* @exception EOFException if this input stream has reached the end.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final boolean readBoolean() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return (ch != 0);
}
/**
* Reads a signed 8-bit value from this data input stream. This
* method reads a byte from the underlying input stream. If the byte
* read is b
, where
* 0 <= b
<= 255, then the
* result is:
*
* (byte)(b)
*
* This method blocks until either the byte is read, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next byte of this input stream as a signed 8-bit
* byte
.
* @exception EOFException if this input stream has reached the end.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final byte readByte() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return (byte)(ch);
}
/**
* Reads an unsigned 8-bit number from this data input stream. This
* method reads a byte from this data input stream's underlying input
* stream and returns that byte. This method blocks until the byte is
* read, the end of the stream is detected, or an exception is thrown.
*
* @return the next byte of this input stream, interpreted as an
* unsigned 8-bit number.
* @exception EOFException if this input stream has reached the end.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final int readUnsignedByte() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return ch;
}
/**
* Reads a signed 16-bit number from this data input stream. The
* method reads two bytes from the underlying input stream. If the two
* bytes read, in order, are b1
and b2
,
* where each of the two values is between 0
and
* 255
, inclusive, then the result is equal to:
*
* (short)((b1 << 8) | b2)
*
* This method blocks until the two bytes are read, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next two bytes of this input stream, interpreted as a
* signed 16-bit number.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final short readShort() throws IOException {
InputStream in = this.in;
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (short)((ch1 << 8) + (ch2 << 0));
}
/**
* Reads an unsigned 16-bit number from this data input stream. This
* method reads two bytes from the underlying input stream. If the
* bytes read, in order, are b1
and b2
,
* where 0 <= b1
,
* b2 <= 255
, then the result is equal to:
*
* (b1 << 8) | b2
*
* This method blocks until the two bytes are read, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next two bytes of this input stream, interpreted as an
* unsigned 16-bit integer.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final int readUnsignedShort() throws IOException {
InputStream in = this.in;
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
/**
* Reads a Unicode character from this data input stream. This
* method reads two bytes from the underlying input stream. If the
* bytes read, in order, are b1
and b2
,
* where 0 <= b1
,
* b1
<= 255, then the result is equal to:
*
* (char)((b1 << 8) | b2)
*
* This method blocks until either the two bytes are read, the end of
* the stream is detected, or an exception is thrown.
*
* @return the next two bytes of this input stream as a Unicode
* character.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final char readChar() throws IOException {
InputStream in = this.in;
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (char)((ch1 << 8) + (ch2 << 0));
}
/**
* Reads a signed 32-bit integer from this data input stream. This
* method reads four bytes from the underlying input stream. If the
* bytes read, in order, are b1
, b2
,
* b3
, and b4
, where
* 0 <= b1
, b2
,
* b3
, b4
<= 255, then the
* result is equal to:
*
* (b1 << 24) | (b2 << 16) + (b3 << 8) +b4
*
* This method blocks until the four bytes are read, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next four bytes of this input stream, interpreted as an
* int
.
* @exception EOFException if this input stream reaches the end before
* reading four bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final int readInt() throws IOException {
InputStream in = this.in;
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
/**
* Reads a signed 64-bit integer from this data input stream. This
* method reads eight bytes from the underlying input stream. If the
* bytes read, in order, are b1
, b2
,
* b3
, b4
, b5
,
* b6
, b7
, and b8
, where
*
* 0 <= b1, b2, b3, b4, b5, b6, b7, b8 <= 255,
*
* then the result is equal to: *
** ((long)b1 << 56) + ((long)b2 << 48) + * ((long)b3 << 40) + ((long)b4 << 32) + * ((long)b5 << 24) + (b6 << 16) + * (b7 << 8) + b8 *
* This method blocks until the eight bytes are read, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next eight bytes of this input stream, interpreted as a
* long
.
* @exception EOFException if this input stream reaches the end before
* reading eight bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public final long readLong() throws IOException {
InputStream in = this.in;
return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
}
/**
* Reads a float
from this data input stream. This
* method reads an int
value as if by the
* readInt
method and then converts that
* int
to a float
using the
* intBitsToFloat
method in class Float
.
* This method blocks until the four bytes are read, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next four bytes of this input stream, interpreted as a
* float
.
* @exception EOFException if this input stream reaches the end before
* reading four bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.DataInputStream#readInt()
* @see java.lang.Float#intBitsToFloat(int)
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
/**
* Reads a double
from this data input stream. This
* method reads a long
value as if by the
* readLong
method and then converts that
* long
to a double
using the
* longBitsToDouble
method in class Double
.
*
* This method blocks until the eight bytes are read, the end of the
* stream is detected, or an exception is thrown.
*
* @return the next eight bytes of this input stream, interpreted as a
* double
.
* @exception EOFException if this input stream reaches the end before
* reading eight bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.DataInputStream#readLong()
* @see java.lang.Double#longBitsToDouble(long)
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
private char lineBuffer[];
/**
* Reads the next line of text from this data input stream. This
* method successively reads bytes from the underlying input stream
* until it reaches the end of a line of text.
*
* A line of text is terminated by a carriage return character
* ('\r'
), a newline character ('\n'
), a
* carriage return character immediately followed by a newline
* character, or the end of the input stream. The line-terminating
* character(s), if any, are not returned as part of the string that
* is returned.
*
* This method blocks until a newline character is read, a carriage
* return and the byte following it are read (to see if it is a
* newline), the end of the stream is detected, or an exception is
* thrown.
*
* @deprecated This method does not properly convert bytes to characters.
* As of JDK 1.1, the preferred way to read lines of text is via the
* BufferedReader.readLine()
method. Programs that use the
* DataInputStream
class to read lines can be converted to use
* the BufferedReader
class by replacing code of the form
*
DataInputStream d = new DataInputStream(in);
* BufferedReader d
* = new BufferedReader(new InputStreamReader(in));
*
* readUTF(this)
.
* See readUTF(java.io.DataInput)
for a more
* complete description of the format.
* * This method blocks until all the bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return a Unicode string. * @exception EOFException if this input stream reaches the end before * reading all the bytes. * @exception IOException if an I/O error occurs. * @see java.io.DataInputStream#readUTF(java.io.DataInput) */ public final String readUTF() throws IOException { return readUTF(this); } /** * Reads in a string from the specified data input stream. The * string has been encoded using a modified UTF-8 format. *
* The first two bytes are read as if by
* readUnsignedShort
. This value gives the number of
* following bytes that are in the encoded string, not
* the length of the resulting string. The following bytes are then
* interpreted as bytes encoding characters in the UTF-8 format
* and are converted into characters.
*
* This method blocks until all the bytes are read, the end of the * stream is detected, or an exception is thrown. * * @param in a data input stream. * @return a Unicode string. * @exception EOFException if the input stream reaches the end * before all the bytes. * @exception IOException if an I/O error occurs. * @exception UTFDataFormatException if the bytes do not represent a * valid UTF-8 encoding of a Unicode string. * @see java.io.DataInputStream#readUnsignedShort() */ public final static String readUTF(DataInput in) throws IOException { int utflen = in.readUnsignedShort(); char str[] = new char[utflen]; int count = 0; int strlen = 0; while (count < utflen) { int c = in.readUnsignedByte(); int char2, char3; switch (c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx count++; str[strlen++] = (char)c; break; case 12: case 13: // 110x xxxx 10xx xxxx count += 2; if (count > utflen) throw new UTFDataFormatException(); char2 = in.readUnsignedByte(); if ((char2 & 0xC0) != 0x80) throw new UTFDataFormatException(); str[strlen++] = (char)(((c & 0x1F) << 6) | (char2 & 0x3F)); break; case 14: // 1110 xxxx 10xx xxxx 10xx xxxx count += 3; if (count > utflen) throw new UTFDataFormatException(); char2 = in.readUnsignedByte(); char3 = in.readUnsignedByte(); if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) throw new UTFDataFormatException(); str[strlen++] = (char)(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)); break; default: // 10xx xxxx, 1111 xxxx throw new UTFDataFormatException(); } } return new String(str, 0, strlen); } }