/* * @(#)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

* Characters in the range '\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: *

* * @author Arthur van Hoff * @version 1.37, 02/27/97 * @see java.io.DataOutputStream * @since JDK1.0 */ public class DataInputStream extends FilterInputStream implements DataInput { /** * Creates a new data input stream to read data from the specified * input stream. * * @param in the input stream. */ public DataInputStream(InputStream in) { super(in); } /** * Reads up to 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: *

*

* 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: *

*

* 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: *

*

* 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: *

*

* 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: *

*

* 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 *

*

* 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 *

* with * * * @return the next line of text from this input stream. * @exception IOException if an I/O error occurs. * @see java.io.BufferedReader#readLine() * @see java.io.FilterInputStream#in */ public final String readLine() throws IOException { InputStream in = this.in; char buf[] = lineBuffer; if (buf == null) { buf = lineBuffer = new char[128]; } int room = buf.length; int offset = 0; int c; loop: while (true) { switch (c = in.read()) { case -1: case '\n': break loop; case '\r': int c2 = in.read(); if (c2 != '\n') { if (!(in instanceof PushbackInputStream)) { in = this.in = new PushbackInputStream(in); } ((PushbackInputStream)in).unread(c2); } break loop; default: if (--room < 0) { buf = new char[offset + 128]; room = buf.length - offset - 1; System.arraycopy(lineBuffer, 0, buf, 0, offset); lineBuffer = buf; } buf[offset++] = (char) c; break; } } if ((c == -1) && (offset == 0)) { return null; } return String.copyValueOf(buf, 0, offset); } /** * Reads in a string that has been encoded using a modified UTF-8 * format from this data input stream. This method calls * 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); } }